要点与禁忌#

接下来的两个列表主要基于优秀的 gist Effective Modern CMake。那个列表更长、更详细,你也可以一并阅读。

CMake 禁忌#

  • 不要使用全局函数:这包括 link_directoriesinclude_libraries 和类似的。

  • 不要添加不必要的 PUBLIC 依赖:你应该避免强迫用户使用不需要的功能(-Wall),将这些改为 PRIVATE

  • 不要 GLOB 文件:Make 或其他工具不会知道你是否添加了文件而没有重新运行 CMake。注意 CMake 3.12 添加了 CONFIGURE_DEPENDS 标志,如果你需要使用它,这将好得多。

  • 直接链接到已构建的文件:如果可用,始终链接到目标。

  • 永远不要在链接时跳过 PUBLIC/PRIVATE:这会导致所有未来的链接都不需要关键字。

CMake 模式#

  • 将 CMake 视为代码:它就是代码。它应该和其他所有代码一样干净和易读。

  • 以目标为中心思考:你的目标应该代表概念。对于任何需要保持在一起并链接的内容,创建(IMPORTED) 接口(INTERFACE)目标并链接到它。

  • 导出接口:你应该能够从构建或安装目录运行。

  • 编写 Config.cmake 文件:这是库作者应该做来支持客户端的事情。

  • 创建 ALIAS 目标以保持使用一致性:使用 add_subdirectoryfind_package 应该提供相同的目标和命名空间。

  • 将通用功能组合到清晰文档化的函数或宏中:通常函数更好。

  • 使用小写函数名:CMake 函数和宏可以小写或大写调用。始终使用小写。大写用于变量。

  • 使用 cmake_policy 和/或版本范围:策略变更是有原因的。如果必须的话,仅逐项设置旧策略。

选择 2025 年的最低版本#

你本地应该运行哪个最低版本的 CMake,以及你的代码应该支持哪个最低版本?既然你在阅读这篇文章,你应该能够获取到最近几个版本中的某个发布版;这样做,将使你的开发更简单。对于支持,选择最低版本有两种方式:基于添加的功能(这是开发者关心的),或基于常见的预安装 CMake(这是用户关心的)。

永远不要选择比你支持的最老编译器版本更旧的最低版本。CMake 应该总是至少和你使用的编译器一样新。