15. CMake与IDE:生成Visual Studio/Xcode/CodeBlocks工程,CMAKE_GENERATOR的选择

说实话,很多刚接触CMake的朋友都会问一个问题:「CMake不是个构建工具吗?怎么还能生成IDE工程?」

嗯,这确实是CMake最强大的特性之一。它不直接编译代码,而是作为「构建系统的生成器」。你写一份CMakeLists.txt,它就能帮你生成Visual Studio的.sln文件、Xcode的.xcodeproj、或者CodeBlocks的.cbp文件。说白了,CMake是个「万能适配器」

15.1 为什么需要生成IDE工程?

我在项目中遇到过好几次这样的情况:团队里有人用VS,有人用CLion,还有人用Xcode。如果每个人都手写一份工程文件,那维护成本简直不敢想。

CMake的解决方案很简单——你只维护一份CMakeLists.txt,剩下的交给CMAKE_GENERATOR

核心思想:CMake是「元构建系统」,它不直接编译,而是生成其他构建系统能识别的工程文件。

15.2 CMAKE_GENERATOR 是什么?

CMAKE_GENERATOR 是一个CMake变量,它决定了CMake会生成哪种格式的工程文件。你可以把它理解成「输出格式选择器」

常见的生成器有这些:

生成器名称 目标IDE/工具 适用平台 生成的文件
Visual Studio 17 2022 Visual Studio 2022 Windows .sln + .vcxproj
Visual Studio 16 2019 Visual Studio 2019 Windows .sln + .vcxproj
Xcode Xcode macOS .xcodeproj
CodeBlocks - Ninja CodeBlocks 跨平台 .cbp
CodeBlocks - Unix Makefiles CodeBlocks Linux/macOS .cbp
Ninja Ninja(命令行) 跨平台 build.ninja
Unix Makefiles GNU Make Linux/macOS Makefile

小提示:在Windows上,如果你不指定生成器,CMake会自动检测已安装的Visual Studio版本。我个人习惯在命令行里显式指定,避免踩坑。

15.3 如何指定生成器?

有两种方式:

方式一:命令行指定

# 生成Visual Studio 2022工程
cmake -B build -G "Visual Studio 17 2022"

# 生成Xcode工程
cmake -B build -G "Xcode"

# 生成CodeBlocks工程(使用Ninja作为底层构建工具)
cmake -B build -G "CodeBlocks - Ninja"

方式二:在CMakeLists.txt中设置(不推荐)

# 不推荐这样做,会降低跨平台性
set(CMAKE_GENERATOR "Visual Studio 17 2022" CACHE INTERNAL "")

注意:在CMakeLists.txt里硬编码生成器是个坏习惯。你想想看,如果别人在Linux上运行你的CMakeLists.txt,却强制要求生成VS工程,那不就报错了吗?

15.4 生成器与平台架构

这里有个容易忽略的点——生成器还决定了目标架构。比如Visual Studio生成器可以指定是x86还是x64:

# 生成64位工程
cmake -B build -G "Visual Studio 17 2022" -A x64

# 生成32位工程
cmake -B build -G "Visual Studio 17 2022" -A Win32

对于Xcode生成器,你可以指定架构:

# 生成iOS模拟器工程
cmake -B build -G "Xcode" -DCMAKE_OSX_ARCHITECTURES="x86_64"

# 生成真机工程
cmake -B build -G "Xcode" -DCMAKE_OSX_ARCHITECTURES="arm64"

15.5 生成器与构建工具的关系

你可能注意到了,像CodeBlocks - Ninja这样的生成器名字里有两个部分。前半部分是IDE,后半部分是底层构建工具。

为什么会这样?

因为IDE工程文件只是「壳」,真正干活的是底层的构建工具。CodeBlocks本身不编译代码,它调用Ninja或Make来干活。Visual Studio也一样,它调用MSBuild。

我画了张图帮你理解这个关系:

CMake生成器与IDE/构建工具的关系 CMakeLists.txt CMAKE_GENERATOR 选择器 Visual Studio .sln Xcode .xcodeproj CodeBlocks .cbp MSBuild Xcode Build System Ninja / Make

从这张图你能看明白:CMake是「翻译官」,它把你的构建需求翻译成不同IDE能理解的语言。但真正干活的,还是底层的构建工具。

15.6 如何查看可用的生成器?

如果你不确定当前系统支持哪些生成器,可以用这个命令:

cmake --help

输出里会列出所有可用的生成器。比如在Windows上,你可能会看到:

Generators
  Visual Studio 17 2022    = Generates Visual Studio 2022 project files.
  Visual Studio 16 2019    = Generates Visual Studio 2019 project files.
  Visual Studio 15 2017    = Generates Visual Studio 2017 project files.
  Ninja                    = Generates build.ninja files.
  Unix Makefiles           = Generates standard UNIX makefiles.
  CodeBlocks - Ninja       = Generates CodeBlocks project files (Ninja).
  CodeBlocks - Unix Makefiles = Generates CodeBlocks project files (Unix Makefiles).

小技巧:在Windows上,如果你装了多个VS版本,可以用-G参数自由切换。我经常在VS2019和VS2022之间来回切,测试兼容性。

15.7 生成器与预设(Presets)

CMake 3.19之后引入了预设(Presets)功能,可以让你把常用的生成器配置存起来。我个人非常喜欢这个特性。

在项目根目录创建CMakePresets.json

{
  "version": 3,
  "configurePresets": [
    {
      "name": "vs2022-debug",
      "displayName": "VS2022 Debug",
      "generator": "Visual Studio 17 2022",
      "architecture": "x64",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug"
      }
    },
    {
      "name": "xcode-release",
      "displayName": "Xcode Release",
      "generator": "Xcode",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release"
      }
    }
  ]
}

然后一行命令就能切换:

# 使用VS2022 Debug预设
cmake --preset vs2022-debug

# 使用Xcode Release预设
cmake --preset xcode-release

15.8 避坑指南

我曾经在跨平台项目上踩过一个坑:在Windows上生成VS工程后,直接双击.sln文件打开,然后编译——一切正常。但当我用命令行cmake --build时,却报错了。

原因是什么?

因为VS工程默认使用MSBuild,而MSBuild需要指定平台工具集。如果你在CMake里没设置CMAKE_GENERATOR_TOOLSET,它可能默认用了一个不存在的工具集版本。

解决方案:

# 显式指定工具集
cmake -B build -G "Visual Studio 17 2022" -T v143

另一个常见问题是生成器缓存。如果你第一次用-G "Visual Studio 16 2019"生成了工程,第二次想换成-G "Ninja",但忘了删掉build目录——CMake会报错说生成器不匹配。

重要:切换生成器时,一定要清空build目录!否则CMake会拒绝执行。我建议养成习惯:切换生成器前先rm -rf buildrd /s build

15.9 生成器选择策略

说了这么多,到底该怎么选?我总结了几条经验:

  • Windows + Visual Studio用户:选Visual Studio 17 2022,调试体验最好
  • macOS + Xcode用户:选Xcode,原生支持Apple Silicon和iOS
  • Linux开发者:选Ninja,编译速度比Make快很多
  • 跨平台IDE用户:选CodeBlocks - Ninja,兼顾IDE体验和编译速度
  • CI/CD环境:选NinjaUnix Makefiles,轻量无依赖

你想想看,如果团队里有人用VS、有人用CLion、还有人用VSCode,那最好的策略就是每个人各自指定自己想要的生成器。CMakeLists.txt里只写平台无关的逻辑,生成器的选择交给开发者自己。

嗯,这就是CMake的哲学——一次编写,到处生成


本章要点回顾:

  • CMAKE_GENERATOR 决定了CMake输出哪种IDE工程文件
  • 常见生成器:Visual Studio、Xcode、CodeBlocks、Ninja、Unix Makefiles
  • 生成器可以通过-G命令行参数指定,不要在CMakeLists.txt里硬编码
  • 生成器还影响目标架构(x86/x64/arm64)和平台工具集
  • 切换生成器时必须清空build目录
  • CMake Presets可以简化生成器的管理

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