同一根项目下双编译器子项目引发CMake无限循环问题求助
解决方案:根项目统一构建多编译器子项目且支持独立构建
问题根源
直接在子项目的project()命令后使用set(CMAKE_CXX_COMPILER clang++)会触发CMake重新执行编译器检测流程——因为CMake在根项目project()执行后已经确定了全局编译器环境,后续修改编译器变量会导致CMake认为配置需要重新生成,进而陷入无限循环。
可行方案(推荐):利用项目预包含脚本+独立构建判断
该方案既保证根项目构建时子项目使用指定编译器,又支持子项目单独构建。
步骤1:为subproject02添加编译器配置脚本
在subproject02/目录下创建SetClangCompiler.cmake文件:
# 仅在未指定编译器时设置Clang if(NOT CMAKE_C_COMPILER) set(CMAKE_C_COMPILER clang CACHE PATH "C compiler" FORCE) endif() if(NOT CMAKE_CXX_COMPILER) set(CMAKE_CXX_COMPILER clang++ CACHE PATH "C++ compiler" FORCE) endif()
步骤2:修改根项目CMakeLists.txt
在添加subproject02前,通过CMAKE_PROJECT_subproject02_INCLUDE指定预包含脚本,让subproject02在执行project()前加载编译器配置:
cmake_minimum_required(VERSION 3.21...3.27 FATAL_ERROR) project(project DESCRIPTION "A project") # 添加subproject01,使用默认编译器 add_subdirectory(subproject01) # 指定subproject02的预配置脚本,在其project()执行前设置Clang set(CMAKE_PROJECT_subproject02_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/subproject02/SetClangCompiler.cmake") add_subdirectory(subproject02)
步骤3:修改subproject02的CMakeLists.txt
让子项目识别自身是否为独立构建,独立构建时手动加载编译器配置:
cmake_minimum_required(VERSION 3.21...3.27 FATAL_ERROR) # 独立构建时加载Clang配置脚本 if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) include(SetClangCompiler.cmake) endif() project(subproject02 DESCRIPTION "Subproject 02 using Clang") # 添加可执行目标 add_executable(subproject02 subproject02.cpp)
步骤4:保持subproject01的CMakeLists.txt不变
subproject01使用默认编译器,无需修改其配置:
cmake_minimum_required(VERSION 3.21...3.27 FATAL_ERROR) project(subproject01 DESCRIPTION "Subproject 01 using GCC") add_executable(subproject01 subproject01.c)
验证方式
- 独立构建subproject01:进入
subproject01/目录,执行cmake . && make,自动使用GCC编译。 - 独立构建subproject02:进入
subproject02/目录,执行cmake . && make,自动使用Clang编译。 - 根项目统一构建:进入
project/目录,执行cmake . && make,两个子项目分别用对应编译器构建,无循环问题。
内容的提问来源于stack exchange,提问作者ramgorur
相关产品推荐
相关产品推荐

