web-dev-qa-db-ja.com

複数のサブディレクトリを持つ大きなプロジェクトの「CMakeLists.txt」を作成するにはどうすればよいですか?

私はシミュレーションプロジェクトに取り組んでいます:ターゲットプラットフォームから埋め込みCコードベースを取得し、デバッグまたはコードへのシングルステップのためにホストコンピューターでシミュレーションしようとしています。

OS:Ubuntu Linux 14.04、IDE:CodeLite、Makefile Generator:Cmake。プロジェクトのCMakeLists.txtの書き方がわかりません。コードベースの構造は次のとおりです(すべて[〜#〜] c [〜#〜]で記述されています):

|ARQSim\  
|-->ARQSim.h  
|-->ARQSim.c  
|-->BaseStationCode\  
|   |->downlink.c  
|   |->neoncopy.c  
|   |->armCore\  
|   |  |->common\  
|   |  |  |->Bsconfig.h  
|   |  |  |->config.h  
|   |  |->MacSource\  
|   |  |  |->lib\  
|   |  |  |  |->arqCommon.h  
|   |  |  |  |->OverTheAir.h  
|   |  |  |->source\  
|   |  |  |  |->beacon.c  
|   |  |  |  |->proxyDhcp.c  
|   |  |  |  |->ARQ\  
|   |  |  |  |  |->arqCommon.c  
|   |  |  |  |  |->arqInterface.c  
|   |  |  |  |  |->fragmentation\  
|   |  |  |  |  |  |->fragBookkeeping.c  
|   |  |  |  |  |  |->fragProcessAck.c  
|   |  |  |  |  |->reassembly\  
|   |  |  |  |  |  |->reasmBookkeeping.c  
|   |  |  |  |  |  |->reasmProcessAck.c

私はCmakeにまったく慣れていません。私はここStackOverflowでCMakeとスレッドに関する多くのリソースを読みました。しかし、私は毎回混乱します。私が持っているいくつかの質問:

  1. ルートディレクトリに必要なCMakeLists.txtは1つだけですか、それともディレクトリごとに異なるCMakeLists.txtファイルが必要ですか?
  2. CMakeLists.txtにソースファイルを再帰的に追加するにはどうすればよいですか?
  3. MakeFileを生成するためにCMakeLists.txtに入力する必要がある基本的なコマンドは何ですか?

上記のコードの構造に基づく例をいただければ幸いです。

12
Kazi Hasan

ルートディレクトリに必要なCMakeLists.txtは1つだけですか、それともディレクトリごとに異なるCMakeLists.txtファイルが必要ですか?

通常、ツリーの各レベルに1つあり、意味があります

例えば:

root/
+--- CMakeLists.txt             // your root CMakeLists
+--- foo/
|    +--- CMakeLists.txt        // foo component's CMakeLists
|    +--- foo.c
|    +--- tests/
|         +--- CMakeLists.txt   // foo test's CMakeLists
|         +--- foo_tests.c
+--- bar/
     +--- CMakeLists.txt        // bar component's CMakeLists
     +--- bar.c
     +--- bar_impl/             // no CMakeLists for this dir, it is part of bar
     |    +--- bar_impl.c
     +--- tests/
          +--- CMakeLists.txt   // bar test's CMakeLists
          +--- bar_tests.c

プロジェクトルートCMakeLists.txt:

プロジェクトルートCMakeLists.txtで、最小のcmake要件、プロジェクト名を指定し、さまざまなコンポーネントを含むサブディレクトリを含めます

root/CMakeLists.txt

cmake_minimum_required (VERSION 3.5)
project (my_project C)

add_subdirectory(foo)
add_subdirectory(bar)

コンポーネントCMakeLists.txt:

次に、各コンポーネントサブディレクトリに、ライブラリ、実行可能ファイルなどを追加する別のCMakeLists.txtファイルがあります。

root/foo/CMakeLists.txt

add_library(foo foo.c)
target_include_directories(foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

add_subdirectory(tests)

root/foo/tests/CMakeLists.txt

add_executable(foo_test foo_tests.c)
target_link_libraries(foo_test foo)

あなたはバーなどのためにこの構造に従います...

root/foo/CMakeLists.txt

add_library(bar 
    bar.c 
    bar_impl/bar_impl.c)
target_include_directories(bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(bar foo)

add_subdirectory(tests)

root/bar/tests/CMakeLists.txt

add_executable(bar_test bar_tests.c)
target_link_libraries(bar_test bar)

ビルドファイルの生成:

bootstrapビルドに、cmakeをroot/CMakeLists.txtに向けます

cd root
mkdir build
cd build
cmake ..

(または、IDEのビルドマネージャーを使用してビルド構成を生成します)

参考文献

ここで使用したさまざまな関数の詳細については、ドキュメントを参照してください。

最後に、2番目の質問に答えます。

CMakeLists.txtにソースファイルを再帰的に追加するにはどうすればよいですか?

これは推奨されません(詳細については、 このディスカッション を参照してください)。

ターゲットに含める各ファイルを明示的にリストすることをお勧めします。

複数の別々のディレクトリにソースファイルがあり、それらがすべて同じ論理ターゲットに属している場合は、ディレクトリごとにCMakeLists.txtファイルは必要ありません。ファイル名にサブディレクトリをリストするだけです。

例:

foo/
+--- foo.c
+--- bar.c
+--- baz/
     +--- baz.c
     +--- bang.c

上記のすべてのファイルに対して単一のターゲットfooが必要な場合は、次のように作成します。

add_library(foo 
   foo.c
   bar.c
   baz/baz.c
   baz/bang.c)

または、変数を使用してSRCSのリストを格納したい場合

set(SRCS 
   foo.c
   bar.c
   baz/baz.c
   baz/bang.c)

add_library(foo ${SRCS})
15
Steve Lorimer