You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化多CMake目标与子目录的target_sources配置?

优化CMake多目标多目录配置的方案

方案1:顶层统一维护目标列表,子目录批量遍历处理

在顶层CMakeLists.txt中集中定义所有可执行目标的列表:

# 顶层CMakeLists.txt
set(ALL_EXEC_TARGETS T1 T2 T3 ... Tn)

# 遍历创建可执行目标
foreach(TARGET IN LISTS ALL_EXEC_TARGETS)
    add_executable(${TARGET} main_${TARGET}.cpp) # 每个目标的入口文件
    add_subdirectory(subdir1)
    add_subdirectory(subdir2)
    # ... 添加所有子目录
endforeach()

每个子目录的CMakeLists.txt中,遍历顶层传递的目标列表,批量添加当前目录的源文件:

# 子目录CMakeLists.txt
foreach(TARGET IN LISTS ALL_EXEC_TARGETS)
    target_sources(${TARGET} PRIVATE
        file1.cpp
        file1.h
        file2.cpp
        # 新增源文件只需在这里添加一次
    )
endforeach()

优势:新增可执行目标时,仅需修改顶层的ALL_EXEC_TARGETS列表;新增源文件时,仅需在对应子目录的target_sources中添加一次。


方案2:使用对象库复用源文件(CMake推荐方案)

每个子目录先创建对象库(Object Library),将当前目录的源文件编译为可复用的对象文件,再让所有可执行目标链接该对象库:

# 子目录CMakeLists.txt
add_library(subdir_obj OBJECT
    file1.cpp
    file1.h
    file2.cpp
)
# 如果需要编译选项,可在这里统一设置
target_compile_options(subdir_obj PRIVATE -Wall -Wextra)

顶层CMakeLists.txt中创建可执行目标并链接所有子目录的对象库:

# 顶层CMakeLists.txt
set(ALL_EXEC_TARGETS T1 T2 T3 ... Tn)

foreach(TARGET IN LISTS ALL_EXEC_TARGETS)
    add_executable(${TARGET} main_${TARGET}.cpp)
    # 链接所有子目录的对象库
    target_link_libraries(${TARGET} PRIVATE subdir1_obj subdir2_obj ...)
endforeach()

优势:源文件只需在对象库中定义一次,所有目标共享编译成果(避免重复编译);新增目标时仅需修改顶层列表,新增源文件仅需修改对应子目录的对象库定义。


补充技巧

  • 如果部分目标需要额外的专属源文件,可在子目录中通过条件判断追加:
foreach(TARGET IN LISTS ALL_EXEC_TARGETS)
    target_sources(${TARGET} PRIVATE common_file.cpp)
    if(TARGET STREQUAL "T1")
        target_sources(${TARGET} PRIVATE t1专属文件.cpp)
    endif()
endforeach()
  • 尽量避免使用file(GLOB)自动收集源文件,因为CMake不会自动检测新增文件(需手动重新运行cmake),手动列源文件更可靠。

内容的提问来源于stack exchange,提问作者dshin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:35:19