最稳妥方式是add_executable直接列明源文件路径;项目结构简单、文件固定时,显式列举可避免glob未触发重配置、路径错误或误匹配等问题,且cmake仅识别明确指定的文件。

add_executable 时直接列源文件最稳妥
只要项目结构简单、文件数量固定,add_executable 后直接写死路径是最不容易出错的方式。CMake 不会自动扫描或重载文件,它只认你明确写进 target_sources 或 add_executable 的路径。
常见错误是把 main.cpp 拼错成 main.cp,或者路径写成相对 build 目录而非 source 目录 —— CMake 默认以 CMAKE_CURRENT_SOURCE_DIR(即当前 CMakeLists.txt 所在目录)为基准。
-
add_executable(myapp main.cpp src/utils.cpp src/io.h):头文件加进来能让 IDE 正确索引,但不参与编译 - 路径必须是相对于当前
CMakeLists.txt的,不能用../src/main.cpp除非你确定该CMakeLists.txt在子目录里 - 如果用了
set(CMAKE_CXX_STANDARD 17)却忘了配set(CMAKE_CXX_STANDARD_REQUIRED ON),某些旧编译器可能静默降级,导致std::optional等特性不可用
用 file(GLOB_RECURSE ...) 自动收集要加 CONFIGURE_DEPENDS
当源文件频繁增删,手动维护列表太累,file(GLOB_RECURSE ...) 是常用解法,但默认行为有坑:新增 .cpp 文件后,CMake 不会自动 re-run 这条命令,得手动删 build 目录或执行 cmake --build . --clean-first。
加 CONFIGURE_DEPENDS 就能解决——CMake 会在 configure 阶段检查 glob 匹配的文件时间戳,有变化就触发重新生成构建系统。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.cpp src/*.c include/*.h)- 别用
file(GLOB ... *.cpp)而不加CONFIGURE_DEPENDS,否则新加文件根本不会被编译进去 -
GLOB_RECURSE会钻进build/目录找文件,如果 build 目录里意外生成了 .cpp(比如某些代码生成工具),会被误加;建议显式排除:file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.cpp include/*.h),不带通配根目录
多级目录下推荐 aux_source_directory + 子目录 CMakeLists.txt
大型项目通常按模块拆分目录,比如 drivers/、middleware/、app/。这时硬塞一个 GLOB_RECURSE 容易混入不该编译的测试文件或旧草案。
更可控的做法是在每个子目录放一个 CMakeLists.txt,用 aux_source_directory 收集本目录下所有 .c/.cpp,再由主 CMakeLists.txt 用 add_subdirectory 统一接入。
- 子目录
drivers/CMakeLists.txt写:aux_source_directory(. DRV_SOURCES),然后add_library(drivers STATIC ${DRV_SOURCES}) - 主目录写:
add_subdirectory(drivers)和target_link_libraries(myapp PRIVATE drivers) -
aux_source_directory不支持CONFIGURE_DEPENDS,新增文件仍需手动 rerun cmake;但它不递归、不匹配隐藏文件、不碰 build 目录,比裸 GLOB 更干净
target_sources 和 add_executable 的区别不能乱换
这两者语义不同:add_executable(myapp) 声明目标但没给源码,target_sources(myapp PRIVATE ...) 是往已有目标追加源;而 add_executable(myapp a.cpp b.cpp) 是声明+赋源一步到位。
混用会导致重复编译、链接失败或 IDE 显示异常 —— 比如先 add_executable(myapp),又在别处 add_executable(myapp main.cpp),CMake 会报 “duplicate target” 错误。
- 统一用
add_executable(myapp)开头,后面全用target_sources追加,适合需要条件判断是否加某文件的场景 - 如果用了
target_sources,记得指定作用域:PUBLIC(导出头文件路径)、PRIVATE(仅本目标用)、INTERFACE(只导出接口,不编译) - STM32 项目里常见错误:把
startup_stm32f407xx.s加进target_sources却没设set_property(SOURCE startup_stm32f407xx.s PROPERTY LANGUAGE ASM),导致汇编文件被当 C 编译,报error: expected identifier or '('










