现代 CMake 简明教程(一)- CMake 基础 (转载)

系列文章目录

文章目录

前言

用 CMake 来构建 C/C++ 项目是业内的主流做法。最近,我们的项目代码做了一些拆分和合并:引入其他仓库代码,并且将公共部分拆分以供多个仓库同时使用。为此,就得修改项目中的 CMake 以满足需求。

在做这件事情时,过程是相当痛苦的,修改的难度超过了我的预期。这份痛苦的回忆,让我陷入了沉思:这 CMake 咋这么不好使,是我的使用姿势不对吗?CMake 的最佳实践是啥?

在经过一番搜索和学习,我开始了解 Modern CMake 的一些用法与理念,它主张放弃传统的基于变量的方法,而采用基于 target 的结构化模式,使其成为一个更可维护、更直观、更易集成、更具意义的方案。
在这里对自己的学习做一个总结,主要内容包括:

  1. 介绍 Modern CMake 的基础语法与工具,让你对 CMake 能做些啥有更清楚的认识
  2. 介绍 Modern CMake 理念与最佳实践,并给出具体实例

CMake基础

这部分内容是 An Introduction to Modern CMake 的总结,并不会讲的非常详细,希望通过几句话来高度总结各个用法,旨在了解 CMake 有哪能力,如果对某些部分感兴趣请大家自行查阅具体内容。

1. Modern CMake 介绍

  • 为什么需要一个好的构建系统?如果你有以下需求,那么使用 CMake 可以从中获益
    • 你想避免硬编码路径
    • 你需要在多台电脑上建立一个软件包。
    • 你想使用CI(持续集成)。
    • 你需要支持不同的操作系统(甚至可能只是Unix的不同版本)。
    • 你想支持多个编译器
    • 你想使用IDE,但也许并不是所有时间都想使用。
    • 你想要更好地组织程序的结构
    • 你想使用别人的库
    • 你想使用工具,比如Clang-Tidy,来帮助你编写代码。
    • 你想使用调试器
  • 为什么一定是 CMake?其他工具不行吗?
    • 各个 IDE 都支持 CMake,使用 CMake 可以有更大程度的方便, save you life
    • 目前很多 C/C++ 开源项目都在使用 CMake,通过 find CMake 或者 CMake config 很容易将它们集成至你的项目中
    • 使用 CMake 来管理发布,让别人更容易使用你的库
    • 更多理由请参考 19 reasons why CMake is actually awesome
  • 为什么要用现代 CMake?
    • 通常认为 3.1+ 版本是现代 CMake。CMake 是向下兼容的,可以放心使用
    • 至少应该使用你的编译器出来之后的 CMake 版本,因为它需要知道该版本的编译标志等等
    • 高版本 CMake 有更多特性,可以节省数百行和数小时的 CMakeLists.txt 编写工作,长运来看更容易维护

安装 CMake

略,请参考原文

运行 CMake

  • 经典用法
~/package $ mkdir build
~/package $ cd build
~/package/build $ cmake ..
~/package/build $ make
  • 新版本可以简单一点
~/package $ cmake -S . -B build
~/package $ cmake --build build
  • 安装命令
#From the build directory (pick one)
~/package/build $ make install
~/package/build $ cmake --build . --target install
~/package/build $ cmake --install . # CMake 3.15+ only

#From the source directory (pick one)
~/package $ cmake --build build --target install
~/package $ cmake --install build # CMake 3.15+ only
  • 推荐使用--build 用法
  • 通过 -v 显示执行的构建命令: cmake --build build -v
  • 通过 --target 来选择目标:cmake --build --target install
  • 设置CCCXX 环境变量来选择 C/C++ 编译器
~/package/build $ CC=clang CXX=clang++ cmake ..
  • 选择不同的工具进行构建
  • make 通常是默认的,通过 cmake --help 查看支持的构建器
  • cmake -G"My Tool" 设置构建器,例如 cmake -S . -B buildXcode -G"Xcode"
  • 通过-D 来设置选项,例如 cmake -S . -B build -DCMAKE_INSTALL_PREFIX=dist
  • --trace 打印 CMake configure 阶段的输出,例如 cmake -S . -B build --trace

CMake 行为准则(Do's and Don'ts)

  • CMake 应避免的行为(CMake Antipatterns)
    • 不要使用全局函数,例如 link_directoriesinclude_librariesadd_definitions 等,请你忘记它们
    • 不要滥用 PUBLIC,除非有依赖传递,否则请你使用 PRIVATE 替换 PUBLIC
    • 不要使用 GLOB 来添加文件

    如果不重新运行 CMake,Make或者其他工具将不会知道你是否添加了某个文件。值得注意的是,CMake 3.12 添加了一个 CONFIGURE_DEPENDS 标志能够使你更好的完成这件事。

    • 不要直接链接文件:如果可以的话总是链接目标
    • 当链接库文件时,不要省略 PUBLIC或PRIVATE 关键字: 否则会导致未来的链接都没有关键字
  • CMake 应遵守的规范(CMake Antipatterns)
    • 把 CMake 视作代码,保持它的整洁和可读性
    • 围绕 target 构建你的 CMake。将需要的信息打包在 target 里,然后链接那个目标
    • 导出你的接口:你的 CMake 项目应该可以直接构建或者安装。
    • 为库书写一个 Config.cmake 文件:这是一个库作者应该做的,可以方便别人使用你的库
    • 使用 ALAS 目标以保持使用一致性:使用add_subdirectoryfind_package应该提供相同的目标和命名空间。
    • 将常用的功能提取成函数或者宏,通常函数更好
    • 使用小写的函数名,全大写的变量名
    • 使用cmake_policy 和/或 限定版本号范围:每次改变版本特性 (policy) 都要有据可依。应该只有不得不使用旧特性时才降低特性 (policy) 版本。

原文链接:https://blog.csdn.net/weiwei9363/article/details/109290252

后续

  1. 发现老外写的CMake教程真不错,比任何中文版的都清晰易懂,还比官方文档简洁,要说缺点可能就是不是最新的CMake3.0以后的主流写法,不过当前阶段会用更重要。
    CMake part 1: It is a programming language!
posted @ 2022-05-18 11:15  时间的风景  阅读(317)  评论(0编辑  收藏  举报