13

次のディレクトリ構造があるとしましょう。

projects
   |
   +--lib1
   |   |
   |   +-CMakeFiles.txt
   |
   +--lib2
   |   |
   |   +-CMakeFiles.txt
   |
   +--test
       |
       +-CMakeFiles.txt

lib1 / CMakeFiles.txt:

cmake_minimum_required(VERSION 2.0)

add_library(lib1 STATIC lib1.cpp)

lib2 / CMakeFiles.txt:

cmake_minimum_required(VERSION 2.0)

add_subdirectory(../lib1 ${CMAKE_CURRENT_BINARY_DIR}/lib1)
add_library(lib2 STATIC lib2.cpp)
target_link_libraries(lib2 lib1)

test / CMakeFiles.txt:

cmake_minimum_required(VERSION 2.0)
project(test)

add_subdirectory(../lib1 ${CMAKE_CURRENT_BINARY_DIR}/lib1)
add_subdirectory(../lib2 ${CMAKE_CURRENT_BINARY_DIR}/lib2)

add_executable(test main.cpp)
target_link_libraries(test lib1 lib2)

つまり、それらの両方にlib2依存しlib1、依存しています。test(技術的に静的なライブラリは「リンク」しないことを私は知っていますが、それは単なる例です。)

問題は、現在の設定では、lib1が2回コンパイルされることです。1回目は「test」ビルドディレクトリ内にあり、2回目は「test / build_directory / lib2/build_directory」内にあります。それは避けたいです。

lib1、lib2、またはその両方への依存関係を(add_subdirectoryを使用して)他の場所にあるプロジェクトに追加できるようにしたい。したがって、CMakeFilesを移動することはできません。また、ライブラリを何度もコンパイルすることは避けたいと思います。

どうやってやるの?

プラットフォーム:CMakev。2.8.4およびWindowsXP SP3

トップレベルのCMakeLists.txtファイルはオプションではありません。クリーンなトップレベルのディレクトリを維持し、他の場所にある他のプロジェクトにライブラリを含めることができるようにするためです。Windowsなので、「システム全体にパッケージをインストール」することはできません。コンパイラをその場で切り替える機能を失いたくありません。異なるコンパイラで構築されたユーティリティライブラリは、異なるCランタイムライブラリ/ ABIを使用するため、互換性がなくなります。

4

3 に答える 3

15

もう1つの解決策は、サブディレクトリの先頭にガードを追加することです-CMakeLists.txt:

if(TARGET targetname)
    return()
endif(TARGET targetname)

これにより、サブディレクトリが2回追加されたときにcmakeは何もしません(もちろん、そのファイルでtargetnameが定義されている場合)。

これにより、ビルド/ツリー内の任意の場所(最初に追加したモジュールによって異なります)にlib beeingビルドが作成されますが、ビルドは1回だけで、どこにでもリンクされます。

あなたの例では、

if(TARGET lib1)
    return()
endif(TARGET lib1)

lib1/CMakeFiles.txtの上部にあります

于 2012-10-29T20:05:23.790 に答える
7

CMakeでは、ライブラリの依存関係は推移的であるため、add_subdirectory2回呼び出す必要はありません(すでにの依存関係であるため、の依存関係としてtest/CMakeFiles.txtリストする必要もありません)。lib1testlib2

testしたがって、のCMakeFiles.txtを次のように変更できます。

cmake_minimum_required(VERSION 2.8.7)  # Prefer the most current version possible
project(test)

add_subdirectory(../lib2 ${CMAKE_CURRENT_BINARY_DIR}/lib2)

add_executable(test main.cpp)
target_link_libraries(test lib2)

また、cmake_minimum_requiredプロジェクト以外のCMakeFiles.txtファイル(libファイル)から呼び出しを削除する必要があります。詳細については、以下を実行してください。

cmake --help-policy CMP0000


lib1この設定では、と に依存する同様のtest2サブディレクトリとプロジェクトを追加した場合でも、すべてのライブラリが再コンパイルされますlib2。トップレベルのCMakeFiles.txtを本当に入れたくない場合は、実行してprojects/いることに固執するか、exportまたはinstallコマンドを使用できます。

export他のプロジェクトで作成できるファイルを作成し、includeを呼び出すプロジェクトにターゲットをインポートしますinclude

installライブラリをの別の共通サブディレクトリにインストールできprojects/ます。ソースディレクトリの構造によっては、目的のライブラリAPIヘッダーのみを依存プロジェクトで使用できるようにするという利点があります。

ただし、これらのオプションはどちらも、依存ライブラリプロジェクトが変更された場合に再構築(およびインストール)する必要がありますが、現在のセットアップにはプロジェクト内のすべての依存ターゲットが含まれているため、依存ライブラリ内のソースファイルを変更すると、test古くなるターゲット。

exportおよびの詳細については、以下installを実行してください。

cmake --help-command export
cmake --help-command install
于 2012-04-04T20:05:51.670 に答える
0

おそらく、プロジェクトディレクトリにトップレベルのCMakeLists.txtを追加します。何かのようなもの:

project( YourProjects )

add_subdirectory( lib1 )
add_subdirectory( lib2 )
add_subdirectory( test )

これで十分であり、最上位のbuild-dirにsolution-fileまたはmakefileが含まれます。add_subdirectory( ../lib1 ...次に、lib1およびlib2プロジェクトからを削除する必要がありますが、代わりにそれらにリンクするだけです。CMakeは、テストをコンパイルするときにlib1とlib2を見つける方法を知っています。

つまり、lib2の場合:

project( lib2) 
add_library(lib2 STATIC lib2.cpp)
target_link_libraries(lib2 lib1)

とテスト中:

project( test )
add_executable(test main.cpp)
target_link_libraries(test lib1 lib2)

追加されたボーナス:lib2ディレクトリにlib2(依存lib1を含む)を構築するためのmakefiles/solutionfilesを取得します...

于 2012-04-04T14:15:55.850 に答える