CMake 的ExternalProject允许定义如何下载、配置、构建和安装外部项目。所有的步骤都将在构建时执行。
我想在配置主项目期间执行外部项目的配置步骤。外部项目配置完成后,导入目标的描述可用,因此可以加载外部项目的find_package()
功能。
是否可以在配置时构建一些目标?
CMake 的ExternalProject允许定义如何下载、配置、构建和安装外部项目。所有的步骤都将在构建时执行。
我想在配置主项目期间执行外部项目的配置步骤。外部项目配置完成后,导入目标的描述可用,因此可以加载外部项目的find_package()
功能。
是否可以在配置时构建一些目标?
ExternalProject只是要执行的一系列步骤。所以你可以使用它的两个实例:
其他项目/CMakeLists.txt:
project(other_project)
include(ExternalProject)
ExternalProject_Add(<project_name> <options...>
BUILD_COMMAND "" # Disable build step.
INSTALL_COMMAND "" # Disable install step too.
)
CMakeLists.txt:
# The first external project will be built at *configure stage*
execute_process(
COMMAND ${CMAKE_COMMAND} --build . ${CMAKE_SOURCE_DIR}/other_project
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/other_project
)
CMakeLists.txt:
# The second external project will be built at *build stage*
ExternalProject_Add(<project_name> <options...>
CONFIGURE_COMMAND "" # Disable configure step. But other steps will be generated.
)
通过对两个调用使用相同的<options>ExternalProject_Add()
我们实现了对创建的两个外部项目的“抢占”:第二个项目的构建和后续步骤将使用第一个配置步骤的结果。
如果您不想在配置时构建项目†</sup>,而只想下载它,请使用FetchContent。FetchContent_Declare
使用许多与 相同的参数ExternalProject_Add
,但它不允许构建项目。
该文档有一个很好的例子来说明如何使用它:
FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.0 ) FetchContent_GetProperties(googletest) if(NOT googletest_POPULATED) FetchContent_Populate(googletest) add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) endif()
这需要 CMake 3.11 或更高版本。对于以前的版本,您可以从 CMake 存储库中下载该FetchContent.cmake
模块以及FetchContent 目录,确保您遵守 BSD 3-Clause 许可证。
† 在配置时构建有一些严重的缺点。例如,除非您非常仔细地设置,否则您的库的用户无法控制构建过程。包管理器是更好的解决方案
Hunter C++ 包管理器可以满足我的要求。Hunter 基于 CMake ExternalProject,但带有一组预定义项目。此外,它会在配置期间构建依赖项,并且可以通过find_package(... CONFIG)
. 非常好的东西!
从 CMake 3.14 及更高版本开始,这就是您使用 FetchContent 的方式
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.8.0
)
FetchContent_MakeAvailable(googletest)
然后构建你的测试
test/CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(${PROJECT_NAME}_test)
# Tests for mu_project
file(GLOB_RECURSE TEST_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)
add_executable(${PROJECT_NAME}_test ${TEST_SOURCES})
target_link_libraries(${PROJECT_NAME}_test gtest gmock_main)
# Register the tests
add_test(NAME ${PROJECT_NAME}_test
COMMAND ${PROJECT_NAME}_test)
enable_testing()
你现在可以走了