36. 9.4 其他编辑器支持

引言:工具箱里的”特种工兵”

在前几节中,我们的 CMake “施工队长”已经拜访了 Windows 平台上的”老牌监理办公室”(Visual Studio)、跨平台的”管家”(CLion),以及轻量全能的”助理”(VS Code)。不过,开发工具的世界从来不只有这几把交椅。在 C++ 开发的江湖里,依然活跃着一群特立独行的开发者:他们有的钟情于键盘上飞舞的 Vim/Neovim,有的坚守 Emacs 的”神之编辑器”信仰,还有的深耕 Qt 生态,与 Qt Creator 形影不离。

这一节,我们就来盘点这些经典与专用编辑器对 CMake 的支持情况。无论你的”施工指挥部”搭在哪里,CMake 都能把蓝图(构建系统)翻译给它们听懂。我们还会重点介绍一个”秘密武器”——compile_commands.json,它就像一份标准的项目资料卡,能让任何支持 Language Server Protocol(LSP)的编辑器瞬间读懂你的代码结构。

Vim / Neovim 集成:老派工匠的利刃

Vim 和它的现代继任者 Neovim 向来以极致的键盘效率和可定制性著称。但原生的 Vim 对 CMake 一无所知,它就像一把未经开刃的宝刀——锋利潜力都在,需要你手动装上”刀柄”。

cmake4vim:把构建命令映射到快捷键

对于 Vim 用户,cmake4vim 是最成熟的 CMake 集成插件之一。它能把 CMake 的配置、构建、测试流程无缝嵌入 Vim 的操作逻辑中。

安装后(推荐通过 vim-plug 等插件管理器),你可以在 .vimrcinit.vim 中做如下配置:

" 使用 vim-plug 安装
Plug 'ilyachur/cmake4vim'

" 常用快捷键映射(示例)
let g:cmake_build_dir = 'build'
let g:cmake_generate_options = ['-G', 'Ninja']
let g:cmake_compile_commands = 1  " 自动生成 compile_commands.json

nmap <leader>cg :CMakeGenerate<CR>
nmap <leader>cb :CMakeBuild<CR>
nmap <leader>ct :CMakeTest<CR>
nmap <leader>cc :CMakeClean<CR>

cmake4vim 会自动在后台调用 cmake -B build 进行配置,用 cmake --build build 执行编译,并把错误信息捕获到 Vim 的 Quickfix 列表中。按下一个快捷键,你就能像在现代 IDE 里一样”跳转到下一个错误”。

Neovim 的现代方案:vim-cmake 与 LSP 联动

Neovim 用户除了 cmake4vim,还可以选择更轻量的 vim-cmake,或者直接在 Lua 配置中调用 vim.fn.jobstart() 自行封装 CMake 命令。

更重要的是,Neovim 配合 nvim-lspconfigclangd 使用时,只要项目根目录存在 compile_commands.json,就能获得与 VS Code 几乎同等质量的代码补全、跳转和重构体验。我们稍后详细介绍这份”项目资料卡”的生成方法。

Emacs 集成:神之编辑器里的蓝图

Emacs 用户通常追求”一切都在一个进程里解决”。CMake 在 Emacs 中的支持主要依赖 cmake-mode,它通常作为 Emacs 内置包或 MELPA 仓库中的插件提供。

cmake-mode 的基础配置

cmake-mode 能提供 CMakeLists.txt.cmake 脚本的语法高亮、缩进、注释格式化,以及基础的命令补全。如果你使用 use-package 管理配置,可以这样写:

(use-package cmake-mode
  :ensure t
  :mode (("CMakeLists\.txt\'" . cmake-mode)
         ("\.cmake\'" . cmake-mode))
  :hook (cmake-mode . (lambda ()
                        (setq indent-tabs-mode nil)
                        (setq tab-width 2))))

;; 可选:在 Emacs 内直接运行 CMake 构建
(global-set-key (kbd "C-c c g") (lambda () (interactive)
                                  (compile "cmake -B build -S .")))
(global-set-key (kbd "C-c c b") (lambda () (interactive)
                                  (compile "cmake --build build")))

虽然 Emacs 没有官方出品的”重型” CMake IDE 插件,但借助其强大的 M-x compile 命令和错误正则解析(compilation-mode),你完全可以把 CMake 的输出捕获成可点击跳转的链接。对于重度 Emacs 用户来说,这种”够用且透明”的方式反而更对胃口。

Qt Creator:Qt 开发者的原生家园

Qt Creator 是 Qt 框架的官方 IDE,但它对 CMake 的支持近年来已非常成熟,完全可以作为通用 C++ IDE 使用。如果说 CLion 是 CMake 的”知己”,那 Qt Creator 就是 Qt 项目的”亲人”。

打开与导入 CMake 项目

在 Qt Creator 中打开 CMake 项目非常简单:

  1. 选择 File → Open File or Project…
  2. 选中项目根目录的 CMakeLists.txt
  3. Qt Creator 会自动解析项目结构,弹出配置向导,让你选择构建目录、CMake 生成器(Ninja 或 Makefile)、以及工具链(Kit)

与 qmake 项目不同,CMake 项目不需要 .pro 文件。Qt Creator 会直接读取你的 CMakeLists.txt,并在左侧项目浏览器(Project Tree)中展示目标(Targets)和源文件。

Kit 与构建配置

Qt Creator 的核心概念是 Kit(套件),它封装了编译器、调试器、Qt 版本和 CMake 工具。你可以在 Projects → Manage Kits… 中配置多个 Kit,例如:

  • 桌面版 GCC + CMake 3.28
  • Android NDK + CMake(交叉编译)
  • 嵌入式 Linux 工具链

切换 Kit 时,Qt Creator 会自动重新运行 CMake 配置,并在不同的构建目录(通常是 build-<ProjectName>-<KitName>)中生成工程。这与 CMake 的源外构建(Out-of-source)理念天然契合。

特殊支持:AUTOMOC、AUIC、ARRC 的可视化

对于 Qt 项目,Qt Creator 对 CMake 的 qt_add_executableqt_add_qml_module 等现代命令有极佳的语法支持。当你在 CMakeLists.txt 中列出 .ui 文件或 .qrc 资源时,Qt Creator 会自动识别并在构建时调用 uic/rcc,无需额外配置。

compile_commands.json:打通任督二脉的”项目资料卡”

前面反复提到了一个文件——compile_commands.json。它到底是什么?为什么能让 Vim、Emacs、VS Code 甚至 Qt Creator 的代码补全质量产生质的飞跃?

什么是编译数据库(Compilation Database)

compile_commands.json 是 LLVM 社区定义的编译数据库标准格式。它是一个 JSON 数组,记录了项目中每一个源文件的完整编译命令,包括:

  • 编译器路径
  • 所有包含目录(-I
  • 宏定义(-D
  • 编译选项(-std=c++17-Wall 等)

当你使用 clangd 或基于 LSP 的插件时,Language Server 会读取这个文件,从而精确地知道每个文件在编译时的”上下文”。没有它,LSP 就只能瞎猜头文件位置和宏定义,导致补全和跳转频频失误。

用 CMake 生成 compile_commands.json

CMake 内置了对该文件的支持。你只需要在配置阶段打开一个开关:

# 命令行方式
cmake -B build -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

# 或在 CMakeLists.txt 中硬编码(不推荐用于提交,适合个人开发)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

配置完成后,CMake 会在构建目录(如 build/)中生成 compile_commands.json

让编辑器找到它

生成文件只是第一步,你还需要让编辑器/语言服务器定位到它:

  • Vim/Neovim + clangd:clangd 会自动向上查找项目根目录中的 compile_commands.json,或者你可通过 .clangd 配置文件指定 CompilationDatabase: build/
  • Emacs + lsp-mode:确保 lsp-clients-clangd-executable 正确设置,lsp-mode 会自动识别同目录或构建目录中的 JSON 文件。
  • Qt Creator:在 Projects → Build → CMake 配置中勾选 “Generate compilation database”,或在 Additional CMake Options 中填入 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON。Qt Creator 内部的 Clang Code Model 会立刻受益。

如果你把构建目录放在项目根目录下的 build/ 中,大多数工具链都能”自动感应”。但如果目录结构比较复杂(比如 out/debug/),建议手动创建一个软链接:

# 在项目根目录创建软链接,方便所有工具查找
ln -s build/compile_commands.json compile_commands.json

注意:不要把 compile_commands.json 提交到 Git 仓库,把它加入 .gitignore

小结:总有一款适合你的”指挥部”

在这一节中,我们走遍了 CMake 在几种特色编辑器中的落地方式:

  • Vim/Neovim 借助 cmake4vim 等插件,把构建命令锻造成快捷键上的利刃;
  • Emacs 凭借 cmake-mode 和强大的 compile 模式,保持了一贯的透明与可定制;
  • Qt Creator 作为 Qt 生态的原生 IDE,对 CMake 项目的导入和 Kit 管理极为友好;
  • compile_commands.json 则是连接 CMake 与现代 LSP 生态的桥梁,让任何编辑器都能获得精准的代码理解能力。

至此,关于 IDE 与编辑器集成的篇章就告一段落了。从下一章开始,我们的 CMake “施工队长”将正式带领你踏入实战项目的工地——你将看到如何把前面学到的所有知识,编织成一套完整、现代、可交付的 C++ 工程构建体系。敬请期待。

请登录后发表评论

    没有回复内容

正在唤醒异次元光景……