CMake FetchContent无法找到依赖:嵌套Git项目配置失败求助
问题根源
spdlog_setup的CMakeLists.txt依赖判断逻辑为:
if (EXISTS ${CMAKE_SOURCE_DIR}/deps/spdlog/CMakeLists.txt)
add_subdirectory(deps/spdlog)
else()allow usage of installed dependencyfind_package(spdlog ${SPDLOG_MIN_VERSION} REQUIRED)
add_library(${PROJECT_NAME}_spdlog INTERFACE IMPORTED)
endif()
通过FetchContent拉取的spdlog既不在${CMAKE_SOURCE_DIR}/deps/spdlog路径下,也未安装到系统默认位置,导致find_package无法定位到spdlog,最终执行else分支失败。
解决方案
方案1:修改spdlog_setup的依赖检测逻辑
在拉取spdlog_setup前,获取spdlog的源码路径,替换spdlog_setup的CMakeLists.txt中的检测条件,让它识别FetchContent拉取的spdlog:
FetchContent_Declare( spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git GIT_TAG v1.11.0 ) FetchContent_MakeAvailable(spdlog) # 获取spdlog的源码目录 FetchContent_GetProperties(spdlog) if(NOT spdlog_POPULATED) FetchContent_Populate(spdlog) endif() FetchContent_Declare( spdlog_setup GIT_REPOSITORY https://github.com/guangie88/spdlog_setup.git GIT_TAG v0.3.2 ) FetchContent_GetProperties(spdlog_setup) if(NOT spdlog_setup_POPULATED) FetchContent_Populate(spdlog_setup) # 替换spdlog_setup的依赖检测路径 file(READ "${spdlog_setup_SOURCE_DIR}/CMakeLists.txt" setup_cmake_content) string(REPLACE "if (EXISTS ${CMAKE_SOURCE_DIR}/deps/spdlog/CMakeLists.txt)" "if (EXISTS ${spdlog_SOURCE_DIR}/CMakeLists.txt)" setup_cmake_content) file(WRITE "${spdlog_setup_SOURCE_DIR}/CMakeLists.txt" "${setup_cmake_content}") add_subdirectory(${spdlog_setup_SOURCE_DIR} ${spdlog_setup_BINARY_DIR}) endif()
方案2:设置CMAKE_PREFIX_PATH让find_package找到spdlog
FetchContent拉取的spdlog会在构建目录生成配置文件,将该路径添加到CMAKE_PREFIX_PATH,让find_package能搜索到:
FetchContent_Declare( spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git GIT_TAG v1.11.0 ) FetchContent_MakeAvailable(spdlog) # 将spdlog的配置目录加入搜索路径 list(APPEND CMAKE_PREFIX_PATH "${spdlog_BINARY_DIR}") FetchContent_Declare( spdlog_setup GIT_REPOSITORY https://github.com/guangie88/spdlog_setup.git GIT_TAG v0.3.2 ) FetchContent_MakeAvailable(spdlog_setup)
方案3:手动指定spdlog的配置路径
直接设置spdlog_DIR变量,指向spdlog配置文件所在路径,跳过自动搜索:
FetchContent_Declare( spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git GIT_TAG v1.11.0 ) FetchContent_MakeAvailable(spdlog) # 指定spdlog的配置文件路径 set(spdlog_DIR "${spdlog_BINARY_DIR}") FetchContent_Declare( spdlog_setup GIT_REPOSITORY https://github.com/guangie88/spdlog_setup.git GIT_TAG v0.3.2 ) FetchContent_MakeAvailable(spdlog_setup)
说明
方案1通过修改spdlog_setup的检测逻辑适配FetchContent拉取的源码;方案2、3则通过配置CMake搜索路径,让find_package定位到未安装的spdlog。可根据项目需求选择合适方案。
内容的提问来源于stack exchange,提问作者Frank

