23、生成器:Visual Studio生成器、Xcode生成器、Ninja、Makefile生成器、生成器特定设置

说到CMake,有个概念你绕不开——生成器(Generator)。说白了,CMake本身不编译代码,它是个“项目文件生成器”。你写一堆CMakeLists.txt,它帮你生成Visual Studio的.sln、Xcode的.xcodeproj,或者Ninja/Makefile的构建脚本。然后真正的编译工作,交给这些工具去干。

我个人习惯把生成器分成两类:IDE生成器命令行生成器。前者生成的是“工程文件”,你打开IDE就能跑;后者生成的是“构建脚本”,你在终端里敲make或ninja就行。今天咱们就把这几个主流生成器挨个捋一遍。

Visual Studio生成器

Windows上做C++开发,Visual Studio是绕不过去的。CMake对VS的支持非常成熟,从VS 2010到VS 2022,每个版本都有对应的生成器名称。

常用的VS生成器有:

  • Visual Studio 16 2019 —— 对应VS 2019
  • Visual Studio 17 2022 —— 对应VS 2022
  • Visual Studio 15 2017 —— 对应VS 2017

你可能会问:怎么指定用哪个?很简单,在cmake命令行里加 -G 参数:

cmake -G "Visual Studio 17 2022" -A x64 ..

这里 -A x64 指定的是架构。VS生成器支持 Win32x64ARMARM64 等。我在项目中遇到过一个问题:同事没加 -A,结果默认生成了32位工程,链接第三方64位库时死活过不去。嗯,这个坑踩过一次就记住了。

VS生成器还有个特点:它会生成 .sln 和一堆 .vcxproj 文件。你打开 .sln,所有目标(可执行文件、库、测试)都会出现在解决方案里,每个目标一个项目。调试、编译、部署,跟原生VS项目一模一样。

小技巧:如果你在Windows上同时装了VS 2019和VS 2022,可以用 cmake --help 查看所有可用的生成器列表。CMake会自动检测已安装的VS版本。

Xcode生成器

macOS和iOS开发,Xcode是标配。CMake的Xcode生成器会生成 .xcodeproj 文件,你双击就能在Xcode里打开。

用法也很直接:

cmake -G Xcode ..

Xcode生成器有个特别的地方:它支持多架构构建。比如你想同时编译arm64和x86_64的库,可以在CMake里设置:

set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")

然后Xcode生成器会生成一个包含两个架构的工程。你在Xcode里选择“Any Mac”或“Any iOS Simulator”,编译出来的就是通用二进制。我记得第一次用这个功能时,觉得“哇,真方便”——不用手动跑两次编译了。

不过要注意:Xcode生成器生成的工程文件比较大,尤其是项目规模上去之后。我曾经有个项目,CMake配置完生成出来的 .xcodeproj 有200多MB。嗯,这时候你可能要考虑用Ninja了。

Ninja生成器

Ninja是我个人最常用的生成器。它快,真的快。Ninja的设计哲学就是“快”——没有复杂的依赖解析,没有花哨的语法,就是纯纯的构建脚本。

用法:

cmake -G Ninja ..

Ninja生成器会生成一个 build.ninja 文件。你直接敲 ninja 就开始编译了。Ninja支持并行编译,默认会使用所有CPU核心。你想想看,一个大型项目,用Makefile可能要编译5分钟,Ninja可能3分钟就搞定了。

Ninja还有个好处:跨平台。Windows、macOS、Linux都能用。你只需要装好Ninja工具(pip install ninja 或者从官网下载),CMake就能用它生成构建脚本。

注意:Ninja本身不处理依赖关系,它依赖CMake生成的 build.ninja 文件里的依赖信息。所以如果你手动修改了 build.ninja,CMake重新配置时会覆盖掉。别问我怎么知道的——我曾经手贱改过,然后被覆盖了。

Makefile生成器

Makefile生成器是CMake最传统的生成器。在Linux上,默认就是 Unix Makefiles。用法:

cmake -G "Unix Makefiles" ..

在Windows上,如果你装了MinGW或MSYS,也可以用 MinGW MakefilesMSYS Makefiles

Makefile生成器会生成一个 Makefile 文件。你敲 make 就开始编译。它支持 make -j4 并行编译,但说实话,在大型项目上,Makefile的依赖解析速度不如Ninja。我做过对比:一个包含500+源文件的项目,Makefile光解析依赖就要花几秒钟,Ninja几乎是瞬间。

不过Makefile生成器有个优点:几乎任何Unix-like系统都自带make工具,不需要额外安装。对于简单的项目,或者你只是想快速验证一下CMake配置,Makefile生成器完全够用。

生成器特定设置

每个生成器都有自己的“脾气”。CMake提供了一些变量,让你针对不同生成器做特殊配置。

变量名 作用 适用生成器
CMAKE_VS_PLATFORM_NAME 指定VS平台(Win32/x64/ARM) Visual Studio
CMAKE_XCODE_ATTRIBUTE_* 设置Xcode的build settings Xcode
CMAKE_NINJA_OUTPUT_DIR 指定Ninja输出目录 Ninja
CMAKE_MAKE_PROGRAM 指定make工具路径 Makefile

举个例子,在Xcode中你想关闭某个警告,可以这样写:

if(CMAKE_GENERATOR MATCHES "Xcode")
  set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_INHIBIT_ALL_WARNINGS "YES")
endif()

在Visual Studio中,你想指定平台工具集:

if(CMAKE_GENERATOR MATCHES "Visual Studio")
  set(CMAKE_VS_PLATFORM_TOOLSET "v143")  # VS 2022的工具集
endif()

这些生成器特定设置,说白了就是让你“因地制宜”。同一个CMakeLists.txt,在不同平台上生成不同的配置,但逻辑保持一致。我在做跨平台项目时,经常用 CMAKE_GENERATOR 变量做条件判断,确保每个生成器都能输出最优的构建配置。

知识体系图

下面这张图总结了本章的核心内容,帮你快速理清生成器的分类和关系:

CMake 生成器 IDE 生成器 命令行生成器 Visual Studio .sln / .vcxproj Xcode .xcodeproj Ninja build.ninja Makefile Makefile 生成器特定设置 CMAKE_GENERATOR 条件判断 + 各生成器专属变量 选择生成器 = 平衡 开发体验、编译速度、平台需求

核心要点:

  • IDE生成器(VS、Xcode)适合需要图形化调试和项目管理的场景
  • 命令行生成器(Ninja、Makefile)适合CI/CD、服务器构建、追求编译速度的场景
  • Ninja是目前编译速度最快的生成器,强烈推荐用于大型项目
  • Makefile生成器兼容性最好,几乎任何Unix系统都能用
  • 生成器特定设置让你“一套CMake,多平台适配”

好了,生成器这块就聊到这儿。你只要记住:CMake不编译,它只负责“翻译”——把你的CMakeLists.txt翻译成各种构建工具能理解的格式。选对生成器,能让你的开发效率翻倍。

公众号:蓝海资料掘金营,微信deep3321