我正在使用 Cmake 构建一个项目并使用 FetchContent
来管理依赖项。由于多种原因,我不能依赖系统范围内安装的包,所以这个包有很大帮助。它允许我做这样的事情:
cmake_minimum_required(VERSION 3.14)
project(dummy LANGUAGES C CXX)
include(FetchContent)
FetchContent_Declare(nlohmann
GIT_REPOSITORY https://github.com/onavratil-monetplus/json
GIT_TAG v3.7.3
)
FetchContent_MakeAvailable(nlohmann)
add_executable(dummy main.cpp)
target_link_libraries(dummy PUBLIC nlohmann_json::nlohmann_json)
现在只要 repo 是一个带有 CMakeLists.txt
的 cmake 项目,它就可以很好地工作。我很乐意对非 cmake 项目使用类似的方法,例如 Botan 库。显然
FetchContent_Declare(botan
GIT_REPOSITORY https://github.com/onavratil-monetplus/botan
GIT_TAG 2.17.2
)
FetchContent_MakeAvailable(botan)
并没有真正完成工作,构建没有运行,因为它不是 cmake 项目。人们会考虑添加
CONFIGURE_COMMAND "<SOURCE_DIR>/configure.py --prefix=<BINARY_DIR>"
BUILD_COMMAND "cd <SOURCE_DIR> && make"
或类似于 declare 命令的内容,但 FetchContent
文档明确指出这些特定参数在传递给 FetchContent
时会被忽略。
现在问题很明显了——如何在这种情况下正确使用 FetchContent
?我正在考虑在 fetchcontent 之后使用 ExternalProject_Add
,但是 fetchcontent 似乎没用(ExternalProject 也可以下载 git repo)。此外,我想在配置时使用 botan 的一些目标(如果有意义的话)。
最佳答案
我遇到了同样的问题。由于 Botan 库在内部不使用 CMake 构建系统,因此我们无法使用 Botan“目标”。但是可以在 CMake 配置时构建 Botan 库并使用库和头文件。这是我的解决方案(最小配置,仅适用于 MS Visual Studio):
cmake_minimum_required (VERSION 3.20)
if(WIN32)
if(NOT (${CMAKE_BUILD_TYPE} STREQUAL "Release"))
message(FATAL_ERROR "This configuration only works for a Release build")
endif()
# set paths
set(BOTAN_LIB_ROOT_DIR "${CMAKE_SOURCE_DIR}/external/botan")
set(BOTAN_LIB_REPOS_DIR "${BOTAN_LIB_ROOT_DIR}/repos")
set(BOTAN_LIB_FCSTUFF_DIR "${BOTAN_LIB_ROOT_DIR}/cmake-fetchcontent-stuff")
set(BOTAN_LIB_INSTALL_DIR "${BOTAN_LIB_ROOT_DIR}-install")
# download and unpack Botan library
include(FetchContent)
FetchContent_Declare(
botan
GIT_REPOSITORY https://github.com/randombit/botan.git
GIT_TAG 2.19.1
PREFIX ${BOTAN_LIB_FCSTUFF_DIR}
SOURCE_DIR ${BOTAN_LIB_REPOS_DIR}
)
set(FETCHCONTENT_QUIET OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(botan)
# find Python3 Interpreter and run build, testing and installation
if(${botan_POPULATED} AND MSVC AND NOT EXISTS "${BOTAN_LIB_INSTALL_DIR}/lib/botan.lib")
find_package(Python3 COMPONENTS Interpreter)
if(NOT ${Python3_Interpreter_FOUND})
message(FATAL_ERROR "Python3 Interpreter NOT FOUND")
endif()
execute_process(
COMMAND ${Python3_EXECUTABLE} configure.py --cc=msvc --os=windows --prefix=${BOTAN_LIB_INSTALL_DIR}
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake check
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake install
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
endif()
endif()
add_executable (main "main.cpp")
if(WIN32)
target_include_directories(main PUBLIC "${BOTAN_LIB_INSTALL_DIR}/include/botan-2")
target_link_libraries(main PUBLIC "${BOTAN_LIB_INSTALL_DIR}/lib/botan.lib")
configure_file("${BOTAN_LIB_INSTALL_DIR}/bin/botan.dll"
"${CMAKE_CURRENT_BINARY_DIR}/botan.dll"
COPYONLY
)
install(TARGETS main DESTINATION bin)
install(FILES "${BOTAN_LIB_INSTALL_DIR}/bin/botan.dll" DESTINATION bin)
endif()
关于c++ - FetchContent 与 ExternalProject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65232395/