mir*_*fer 95 cmake external-project
我有一个项目A,它导出一个静态库作为目标:
install(TARGETS alib DESTINATION lib EXPORT project_a-targets)
install(EXPORT project_a-targets DESTINATION lib/alib)
Run Code Online (Sandbox Code Playgroud)
现在我想将项目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)
Run Code Online (Sandbox Code Playgroud)
问题是当运行项目B的CMakeLists时,包含文件尚不存在.
有没有办法让include依赖于正在构建的外部项目?
Fra*_*ser 59
我想你在这里混淆了两种不同的范例.
如您所述,高度灵活的ExternalProject模块在构建时运行其命令,因此您无法直接使用Project A的导入文件,因为它仅在安装了Project 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)Run Code Online (Sandbox Code Playgroud)
Tim*_*mmm 17
这篇文章有一个合理的答案:
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 ""
)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
然而,它似乎相当hacky.我想提出一个替代解决方案 - 使用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"
Run Code Online (Sandbox Code Playgroud)
然后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")
Run Code Online (Sandbox Code Playgroud)
我还没有广泛尝试过,但看起来更干净.
编辑:这种方法有一个缺点:子目录可能会运行install()您不想要的命令.这篇文章有一个方法来禁用它们,但它是错误的,并不适合我.
编辑2:如果使用add_subdirectory("googletest" EXCLUDE_FROM_ALL)它似乎意味着install()默认情况下不使用子目录中的命令.
小智 5
我正在寻找类似的解决方案。这里的回复和上面的教程内容丰富。我研究了这里提到的帖子/博客来使我的成功。我发布了对我有用的完整 CMakeLists.txt 。我想,这作为初学者的基本模板会很有帮助。
"CMakeLists.txt"
cmake_minimum_required(VERSION 3.10.2)
# Target Project
project (ClientProgram)
# Begin: Including Sources and Headers
include_directories(include)
file (GLOB SOURCES "src/*.c")
# End: Including Sources and Headers
# Begin: Generate executables
add_executable (ClientProgram ${SOURCES})
# End: Generate executables
# This Project Depends on External Project(s)
include (ExternalProject)
# Begin: External Third Party Library
set (libTLS ThirdPartyTlsLibrary)
ExternalProject_Add (${libTLS}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/${libTLS}
# Begin: Download Archive from Web Server
URL http://myproject.com/MyLibrary.tgz
URL_HASH SHA1=<expected_sha1sum_of_above_tgz_file>
DOWNLOAD_NO_PROGRESS ON
# End: Download Archive from Web Server
# Begin: Download Source from GIT Repository
# GIT_REPOSITORY https://github.com/<project>.git
# GIT_TAG <Refer github.com releases -> Tags>
# GIT_SHALLOW ON
# End: Download Source from GIT Repository
# Begin: CMAKE Comamnd Argiments
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/${libTLS}
CMAKE_ARGS -DUSE_SHARED_LIBRARY:BOOL=ON
# End: CMAKE Comamnd Argiments
)
# The above ExternalProject_Add(...) construct wil take care of \
# 1. Downloading sources
# 2. Building Object files
# 3. Install under DCMAKE_INSTALL_PREFIX Directory
# Acquire Installation Directory of
ExternalProject_Get_Property (${libTLS} install_dir)
# Begin: Importing Headers & Library of Third Party built using ExternalProject_Add(...)
# Include PATH that has headers required by Target Project
include_directories (${install_dir}/include)
# Import librarues from External Project required by Target Project
add_library (lmytls SHARED IMPORTED)
set_target_properties (lmytls PROPERTIES IMPORTED_LOCATION ${install_dir}/lib/libmytls.so)
add_library (lmyxdot509 SHARED IMPORTED)
set_target_properties(lmyxdot509 PROPERTIES IMPORTED_LOCATION ${install_dir}/lib/libmyxdot509.so)
# End: Importing Headers & Library of Third Party built using ExternalProject_Add(...)
# End: External Third Party Library
# Begin: Target Project depends on Third Party Component
add_dependencies(ClientProgram ${libTLS})
# End: Target Project depends on Third Party Component
# Refer libraries added above used by Target Project
target_link_libraries (ClientProgram lmytls lmyxdot509)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
82903 次 |
| 最近记录: |