ターゲットとして静的ライブラリをエクスポートするプロジェクトAがあります。
install(TARGETS alib DESTINATION lib EXPORT project_a-targets)
install(EXPORT project_a-targets DESTINATION lib/alib)
次に、プロジェクトAをプロジェクトBの外部プロジェクトとして使用し、ビルドされたターゲットを含めます。
ExternalProject_Add(project_a
URL ...project_a.tar.gz
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/project_a
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
)
include(${CMAKE_CURRENT_BINARY_DIR}/lib/project_a/project_a-targets.cmake)
問題は、プロジェクトBのCMakeListsを実行したときにインクルードファイルがまだ存在しないことです。
インクルードをビルド中の外部プロジェクトに依存させる方法はありますか?
Update:短い CMake by Example tutorial これに基づいて書いたそして私が遭遇した他の一般的な問題。
ここでは、2つの異なるパラダイムを混在させていると思います。
既に述べたように、非常に柔軟な ExternalProject
モジュールはビルド時にコマンドを実行するため、プロジェクトAがインストールされた後にのみ作成されるため、プロジェクトAのインポートファイルを直接使用することはできません。
include
プロジェクトAのインポートファイルが必要な場合は、haveを使用して、プロジェクトBのCMakeLists.txtを呼び出す前にプロジェクトAを手動でインストールします。 -party依存関係は、この方法またはfind_file
/find_library
/find_package
を介して追加されました。
ExternalProject_Add
を使用する場合は、次のようなものをCMakeLists.txtに追加する必要があります。
ExternalProject_Add(project_a
URL ...project_a.tar.gz
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/project_a
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
)
include(${CMAKE_CURRENT_BINARY_DIR}/lib/project_a/project_a-targets.cmake)
ExternalProject_Get_Property(project_a install_dir)
include_directories(${install_dir}/include)
add_dependencies(project_b_exe project_a)
target_link_libraries(project_b_exe ${install_dir}/lib/alib.lib)
この投稿 には合理的な答えがあります:
CMakeLists.txt.in
:
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
CMakeLists.txt
:
# Download and unpack googletest at configure time
configure_file(CMakeLists.txt.in
googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )
execute_process(COMMAND ${CMAKE_COMMAND} --build .
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )
# Prevent GoogleTest from overriding our compiler/linker options
# when building with Visual Studio
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This adds
# the following targets: gtest, gtest_main, gmock
# and gmock_main
add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src
${CMAKE_BINARY_DIR}/googletest-build)
# The gtest/gmock targets carry header search path
# dependencies automatically when using CMake 2.8.11 or
# later. Otherwise we have to add them here ourselves.
if (CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories("${gtest_SOURCE_DIR}/include"
"${gmock_SOURCE_DIR}/include")
endif()
# Now simply link your own targets against gtest, gmock,
# etc. as appropriate
しかし、それはかなりハックのように見えます。代替ソリューションを提案したいと思います-Gitサブモジュールを使用します。
cd MyProject/dependencies/gtest
git submodule add https://github.com/google/googletest.git
cd googletest
git checkout release-1.8.0
cd ../../..
git add *
git commit -m "Add googletest"
次に、MyProject/dependencies/gtest/CMakeList.txt
で次のようなことができます。
cmake_minimum_required(VERSION 3.3)
if(TARGET gtest) # To avoid diamond dependencies; may not be necessary depending on you project.
return()
endif()
add_subdirectory("googletest")
私はまだこれを広範囲に試したことはありませんが、よりきれいに見えます。
編集:このアプローチには欠点があります。サブディレクトリは、不要なinstall()
コマンドを実行する可能性があります。 この投稿にはそれらを無効にするアプローチがあります しかしバグがあり、私にとってはうまくいきませんでした。
編集2:add_subdirectory("googletest" EXCLUDE_FROM_ALL)
を使用する場合、サブディレクトリ内のinstall()
コマンドはデフォルトでは使用されないようです。
セカンダリメイクプロセスで依存ターゲットのビルドを強制することもできます
関連トピックの my answer を参照してください。
試すことができるのは、project_a
内でcmakeの export コマンドを使用することです。 cmakeの実行時にEXPORT option
ファイルを生成するという点で、project_a-targets.cmake
とともにinstall
コマンドを使用した場合と少し異なります。 project_a-targets.cmake
ファイル内で生成されたインポートターゲットは、ビルドコマンドを実行した後にのみ生成されるプロジェクトのバイナリディレクトリ内の既存のライブラリファイルを最初に指しません。
私が話していることをよりよく理解するには、単純なライブラリを作成する小さなcmakeプロジェクトを作成し、その後にエクスポートコマンドを続けます(以下のコードはテストされていません)。
add_library (project_a lib.cpp)
export (
TARGETS
project_a
FILE
project_a-targets.cmake
)
単純な例でcmakeコマンドを実行すると、バイナリディレクトリ内(またはその子フォルダーのいずれか)でproject_a-targets.cmake
を見つけることができるはずです。ファイルを調べると、現在存在しないライブラリファイルを指していることがわかります。ビルドコマンドを実行した後にのみ、ライブラリが存在します。
問題に戻ると、project-a
のCMakeLists.txt
を更新してexport
コマンドを含める必要があります。次に、ExternalProject_Add
が処理された後、project_a-targets.cmake
を生成する構成ステップを呼び出してから、動作するinclude(.../project_a-targets.cmake)
を呼び出すことができることを確認する必要があります。最後に、project_b
とproject_a
の間に依存関係を追加して、project_a
をビルドする前にproject_b
を強制的にビルドする必要があります。