如何为深度嵌套的科学软件项目编写可管控编译的CMakeLists.txt?
适配需求的CMakeLists.txt编写方案
根目录CMakeLists.txt完整代码
# 指定CMake最低版本要求,可根据编译器支持情况调整(如3.16+适配主流编译器) cmake_minimum_required(VERSION 3.16) # 项目名称,可自定义 project(my_science_app) # 设置C++标准,科学软件推荐C++17及以上,按需调整 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 定义可执行文件编译开关,默认开启所有编译 option(BUILD_MAIN1 "编译main1可执行文件" ON) option(BUILD_MAIN2 "编译main2可执行文件" ON) # 递归收集core目录下所有源文件(.cc),适配任意数量子目录与文件 file(GLOB_RECURSE CORE_SOURCES "${CMAKE_SOURCE_DIR}/core/*.cc" ) # 整理core及子目录的头文件路径,用于编译器查找头文件 set(CORE_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/core" "${CMAKE_SOURCE_DIR}/core/algorithms" "${CMAKE_SOURCE_DIR}/core/algorithms/trees" ) # 处理main1可执行文件的编译逻辑 if(BUILD_MAIN1) # 收集apps/biosimulations目录下的所有源文件 file(GLOB MAIN1_SOURCES "${CMAKE_SOURCE_DIR}/apps/biosimulations/*.cc" ) # 生成可执行文件,合并core源码与main1专属源码 add_executable(main1 ${MAIN1_SOURCES} ${CORE_SOURCES}) # 指定头文件包含目录,确保编译器能找到所有.hh文件 target_include_directories(main1 PRIVATE ${CORE_INCLUDE_DIRS} "${CMAKE_SOURCE_DIR}/apps" "${CMAKE_SOURCE_DIR}/apps/biosimulations" ) endif() # 处理main2可执行文件的编译逻辑 if(BUILD_MAIN2) # 收集core/algorithms/trees目录下的所有源文件(包含main2源码) file(GLOB MAIN2_SOURCES "${CMAKE_SOURCE_DIR}/core/algorithms/trees/*.cc" ) # 生成可执行文件,合并core源码与main2专属源码 add_executable(main2 ${MAIN2_SOURCES} ${CORE_SOURCES}) # 指定头文件包含目录 target_include_directories(main2 PRIVATE ${CORE_INCLUDE_DIRS} "${CMAKE_SOURCE_DIR}/apps" # 若main2无需apps目录头文件,可删除此行 ) endif()
关键逻辑说明
- 编译开关控制:通过
option定义的BUILD_MAIN1和BUILD_MAIN2变量,默认开启编译。如需关闭某个可执行文件,在cmake配置阶段添加参数即可,例如:# 关闭main1的编译,仅编译main2 cmake -S . -B build -DBUILD_MAIN1=OFF - 源码收集:使用
file(GLOB_RECURSE)递归收集目录下所有源文件,无需手动逐个添加,适配任意数量的新增文件(新增文件后需重新运行cmake配置)。 - 头文件路径配置:通过
target_include_directories指定所有涉及的头文件目录,确保编译器能正确找到.hh头文件。 - 无库编译:直接将core目录的源码与可执行文件专属源码合并编译,符合“无静态/动态库,所有源码属于可执行组成部分”的需求。
使用步骤
- 在
my_app_src根目录新建CMakeLists.txt,粘贴上述代码。 - 打开终端,进入
my_app_src目录,执行cmake配置命令:cmake -S . -B build - 进入
build目录,执行编译命令(如VS可直接打开生成的.sln文件,或使用make/ninja等工具编译)。
内容的提问来源于stack exchange,提问作者user366312
相关产品推荐
相关产品推荐

