CMake使用FetchContent后设置CMAKE_TOOLCHAIN_FILE不生效如何解决
问题原因
- CMake仅会在第一次执行
project()命令时读取CMAKE_TOOLCHAIN_FILE变量并加载工具链,工具链初始化完成后,后续修改该变量不会触发重新加载,也不会更新编译器等全局配置。 FetchContent_MakeAvailable除了下载依赖外,还会自动执行add_subdirectory()引入依赖项目,如果第三方依赖的CMakeLists包含project()命令,会在这个阶段触发第一次project()执行,此时你还未设置自定义工具链,默认用了系统工具链,后续修改自然不生效。
解决方案
使用FetchContent_Populate代替FetchContent_MakeAvailable,前者只会完成依赖的下载、解压操作,不会执行add_subdirectory,也就不会提前触发project()调用,你可以在下载完成拿到依赖路径后先设置工具链,再执行自己的project()命令。
修改后的代码示例
cmake_minimum_required(VERSION 3.15) include(FetchContent) FetchContent_Declare( some_software GIT_REPOSITORY https://github.com/some_company/some_software GIT_TAG master ) # 仅下载填充依赖,不执行构建配置 FetchContent_Populate(some_software) # 此时some_software_SOURCE_DIR已经可用,设置工具链 set(CMAKE_TOOLCHAIN_FILE "${some_software_SOURCE_DIR}/toolchain.cmake" CACHE PATH "Toolchain file" FORCE) # 第一次project调用在此处,会正常加载上面设置的工具链 project(my_software) message("CMAKE_TOOLCHAIN_FILE ${CMAKE_TOOLCHAIN_FILE}") message("CMAKE_C_COMPILER ${CMAKE_C_COMPILER}") message("CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER}") # 如果需要将some_software加入当前构建,在此处手动add_subdirectory即可 add_subdirectory(${some_software_SOURCE_DIR} ${some_software_BINARY_DIR}) # 后续你的项目配置逻辑 ...
注意事项
FetchContent_Populate内置缓存逻辑,仅第一次配置时会下载依赖,后续配置会直接复用已下载的内容,不会重复拉取。- 该方案完全在配置阶段完成依赖下载,不需要额外拆分脚本,也不需要用到
ExternalProject。
内容的提问来源于stack exchange,提问作者Fabian
相关产品推荐
相关产品推荐

