我有一个出口静态库作为目标的一个项目:
install(TARGETS alib DESTINATION lib EXPORT project_a-targets)
install(EXPORT project_a-targets DESTINATION lib/alib)
现在,我想用一个项目从项目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当文件尚不存在。
有没有一种方法,使包括依赖于外部项目正在兴建?
更新 :我写了一个简短的CMake通过实例教程在此基础上,我遇到的其他常见问题。
我觉得你在这里混淆了两个不同的范式。
正如你提到的,高度灵活的ExternalProject
模块运行在编译的时候它的命令,所以你不能直接使用A计划的导入文件的,因为一旦一个项目已经安装它不仅创造。
如果要include
项目A的导入文件,你就必须调用项目B的的CMakeLists.txt之前手动安装Project A -就像任何其他第三方的依赖性增加这种方式或通过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()
中不使用默认的子目录命令。
你可以尝试做的是使用的cmake的出口的内命令project_a
。 它的工作原理有点不同,然后使用install
用命令EXPORT option
,它会产生一个你project_a-targets.cmake
运行cmake的时候文件。 在内部生成的进口目标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
。