IDE 集成指南

简介

集成开发环境(IDE)可能希望与 CMake 集成,以改善 CMake 用户的开发体验。本文档阐述了此类集成的推荐最佳实践。

捆绑

许多 IDE 供应商会希望将其 IDE 与 CMake 的副本捆绑在一起。捆绑 CMake 的 IDE 应向用户提供使用外部 CMake 安装的选项,以防捆绑副本过时而用户想使用较新版本。

尽管 IDE 供应商可能倾向于捆绑不同版本的 CMake 与其应用程序,但这种做法不推荐。CMake 对向后兼容性有很强的保证,并且没有理由不使用比项目要求更新的 CMake 版本,或者确实,最新的版本。因此,建议将 CMake 与其应用程序捆绑的 IDE 供应商始终包含发布时可用的最新补丁版本的 CMake。

建议 IDE 也可以随 CMake 一起提供一份 Ninja 构建系统。Ninja 性能极高,并在所有支持 CMake 的平台上都得到良好支持。捆绑 Ninja 的 IDE 应使用 Ninja 1.10 或更高版本,该版本包含支持 Fortran 构建所需的功能。

预设

CMake 支持一种名为 CMakePresets.json 的文件格式,以及其用户专用版本 CMakeUserPresets.json。此文件包含用户可能需要的各种配置预设的信息。每个预设可以有不同的编译器、构建标志等。此格式的详细信息在 cmake(1) 手册中解释。

鼓励 IDE 供应商以 CMake 相同的方式读取和评估此文件,并向用户显示文件中列出的预设。用户应该能够查看(并可能编辑)为给定预设定义的 CMake 缓存变量、环境变量和命令行选项。然后,IDE 应该根据这些设置构建适当的 cmake(1) 命令行参数列表,而不是直接使用 --preset= 选项。--preset= 选项仅旨在作为命令行用户的便捷前端,不应由 IDE 使用。

例如,如果一个名为 ninja 的预设指定 Ninja 为生成器,${sourceDir}/build 为构建目录,则 IDE 不应运行

cmake -S /path/to/source --preset=ninja

而是应该计算 ninja 预设的设置,然后运行

cmake -S /path/to/source -B /path/to/source/build -G Ninja

如果预设包含大量缓存变量,并且将所有变量作为 -D 标志传递会导致超出平台的命令行长度限制,IDE 应改为构建一个临时缓存脚本并使用 -C 标志传递它。

虽然读取、解析和评估 CMakePresets.json 的内容很简单,但并非微不足道。除了文档,IDE 供应商可能还希望参考 CMake 源代码和测试用例,以便更好地理解如何实现该格式。此文件 提供了 CMakePresets.json 格式的机器可读 JSON 模式,IDE 供应商可能会发现它对于验证和提供编辑帮助很有用。

配置

调用 cmake(1) 运行配置步骤的 IDE 可能希望接收有关构建将产生的工件以及用于构建工件的包含目录、编译定义等信息。这些信息可以通过使用 文件 API 获取。文件 API 的手册页包含有关 API 以及如何调用它的更多信息。服务器模式 在 CMake 3.20 中已移除,不应在 CMake 3.14 或更高版本上使用。

IDE 应避免创建不必要的构建树,并且仅在用户希望切换到不同编译器、使用不同编译标志等情况下才创建多个构建树。特别是,IDE 不应创建多个单配置构建树,这些构建树除了不同的 CMAKE_BUILD_TYPE 之外都具有相同的属性,从而有效地创建了一个多配置环境。相反,应将 Ninja 多配置 生成器与 文件 API 结合使用以获取构建配置列表,用于此目的。

IDE 不应使用带有 Makefile 或 Ninja 生成器的“额外生成器”,这些生成器除了 Makefile 或 Ninja 文件之外还会生成 IDE 项目文件。相反,应使用 文件 API 来获取构建工件列表。

构建

如果使用 Makefile 或 Ninja 生成器生成构建树,则不建议直接调用 makeninja。相反,建议 IDE 使用 --build 参数调用 cmake(1),这反过来将调用适当的构建工具。

如果使用了 IDE 项目生成器,例如 XcodeVisual Studio 生成器 之一,并且 IDE 理解所使用的项目格式,则 IDE 应读取项目文件并以其通常的方式构建它。

文件 API 可用于从构建树中获取构建配置列表,IDE 应将此列表呈现给用户以选择构建配置。

测试

ctest(1) 支持输出包含可用测试和测试配置信息的 JSON 格式。希望运行 CTest 的 IDE 应该获取这些信息并使用它来向用户呈现测试列表。

IDE 不应调用生成构建系统的 test 目标。相反,它们应该直接调用 ctest(1)

集成 CMake 的 IDE

以下 IDE 原生支持 CMake

此外,CMake 内置支持某些 IDE