add_executable定义可执行目标而非直接生成二进制,必须先创建目标才能配置属性、链接库等;目标名全局唯一,源文件可后续用target_sources添加,WIN32/MACOSX_BUNDLE切换入口点与打包格式,EXCLUDE_FROM_ALL仅排除默认构建。

add_executable 不是“写完就跑”的命令,它定义的是构建系统里一个**可执行目标**,不是直接生成二进制文件的魔法开关。你得先理解它在 CMake 构建流程里的位置:它是创建目标的起点,后续所有配置(头文件路径、链接库、编译选项)都依赖这个目标名。
什么时候必须用 add_executable?
只要你要生成一个能 ./xxx 运行的程序,就必须调用它。哪怕只有一个 main.cpp,也绕不开:add_executable(myapp main.cpp) 是最简合法形式。
- 目标名
myapp必须全局唯一——同一CMakeLists.txt或include的子目录中,不能有两个add_executable(myapp ...) - 源文件列表可以为空:
add_executable(myapp)合法,但后续必须用target_sources(myapp PRIVATE xxx.cpp)补上,否则链接失败 - 不要把头文件当编译单元硬塞进去——虽然
add_executable(myapp main.cpp utils.h)不报错,但.h不参与编译,只影响 IDE 索引和依赖检查
WIN32 和 MACOSX_BUNDLE 参数到底改了什么?
它们不是“让程序能在 Windows/macOS 上跑”,而是**切换入口点和打包格式**:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
add_executable(gui_app WIN32 main.cpp)→ 链接时加/subsystem:windows(MSVC)或-mwindows(MinGW),入口函数变成WinMain,控制台窗口不弹出 -
add_executable(mac_app MACOSX_BUNDLE main.m)→ 输出不是mac_app,而是mac_app.app/Contents/MacOS/mac_app,且自动带 Info.plist - Linux 下写
WIN32会被忽略;macOS 下写WIN32会报错(CMake 3.15+)
为什么源文件不能全靠 aux_source_directory 自动发现?
因为 aux_source_directory 有三个硬伤:
- 不递归——只扫当前目录,子目录下的
.cpp不会进列表 - 不可控——它把所有
.cpp都塞进去,包括测试文件、旧废弃文件、甚至main.cpp被漏掉(如果文件名不标准) - 破坏可重现性——Git 新增一个
.cpp,构建行为就变,CI 里容易出幺蛾子 - 正确做法是显式列出关键源文件,用
target_sources按条件追加:if(UNIX) target_sources(myapp PRIVATE unix_impl.cpp) endif()
EXCLUDE_FROM_ALL 的真实用途是什么?
它不是“禁用构建”,而是“不加入默认目标”——也就是你敲 make 或 cmake --build . 时,它不会被编译。但它依然存在,且可被显式构建:
-
add_executable(test_runner test.cpp EXCLUDE_FROM_ALL)→make test_runner或cmake --build . --target test_runner才会编译它 - 常用于测试程序、工具脚本、文档生成器等非主程序目标
- 注意:如果该目标被其他目标通过
target_link_libraries依赖,EXCLUDE_FROM_ALL会失效——CMake 会为满足依赖把它拉进来
myapp)和最终输出文件名不是一回事。你用 set_target_properties(myapp PROPERTIES OUTPUT_NAME "cool-app") 可以改二进制名,但所有 target_* 命令仍必须用原始目标名 myapp ——拼错就等于操作了另一个不存在的目标。

















