传统的 CMake 软件构建/安装方式

mkdir build: 需要先创建 build 目录
cd build:切换到 build 目录
cmake ..: 在 build 目录运行 cmake <源码目录> 生成 Makefile
make -j4: 执行本地的构建系统 make 真正开始构建(4进程并行)
sudo make install: 让本地的构建系统执行安装步骤
cd ..:回到源码目录

现代 CMake 提供了更方便的 -B 和 —build 指令,不同平台,统一命令!

cmake -B build: 在源码目录用 -B 直接创建 build 目录并生成 build/Makefile

  • cmake -B build 免去了先创建 build 目录再切换进去再指定源码目录的麻烦。

cmake --build build -j4: 自动调用本地的构建系统在 build 里构建,即:make -C build -j4

  • cmake --build build 统一了不同平台(Linux 上会调用 make,Windows 上调用 devenv.exe)

sudo cmake --build build --target install: 调用本地的构建系统执行 install 这个目标,即安装

结论:从现在开始,如果在命令行操作 cmake,请使用更方便的 -B 和 —build 命令。

-D 选项:指定配置变量(又称缓存变量)

CMake 项目的构建分为两步

  • 第一步是 cmake -B build,称为配置阶段(configure),这时只检测环境并生成构建规则会在 build 目录下生成本地构建系统能识别的项目文件(Makefile 或是 .sln)

构建模式: -DCMAKE_BUILD_TYPE

  • cmake -B build -DCMAKE_BUILD_TYPE=Release: 设置构建模式为发布模式(开启全部优化)
  • cmake -B build -DCMAKE_BUILD_TYPE=Debug

设置安装路径:-DCMAKE_INSTALL_PREFIX

  • cmake -B build -DCMAKE_INSTALL_PREFIX=/opt/openvdb-8.0: 设置安装路径为 /opt/openvdb-8.0(会安装到 /opt/openvdb-8.0/lib/libopenvdb.so)

第二次配置时,之前的-D添加仍然会被保留。除非删除Build

  • 第二步是 cmake --build build,称为构建阶段(build),这时才实际调用编译器来编译代码在配置阶段可以通过-D设置缓存变量。

-G 选项:指定要用的生成器

  • 众所周知,CMake 是一个跨平台的构建系统,可以从 CMakeLists.txt 生成不同类型的构建系统(比如 Linux 的 make,Windows 的 MSBuild),从而让构建规则可以只写一份,跨平台使用。
  • 过去的软件(例如 TBB)要跨平台,只好 Makefile 的构建规则写一份,MSBuild 也写一份。
  • 现在只需要写一次 CMakeLists.txt,他会视不同的操作系统,生成不同构建系统的规则文件。
  • 那个和操作系统绑定的构建系统(make、MSBuild)称为本地构建系统(native buildsystem)。
  • 负责从 CMakeLists.txt 生成本地构建系统构建规则文件的,称为生成器(generator)。

image.png

  • Linux 系统上的 CMake 默认用是 Unix Makefiles 生成器;Windows 系统默认是 Visual Studio 2019 生成器;MacOS 系统默认是 Xcode 生成器。
  • 可以用 -G 参数改用别的生成器,例如 cmake -GNinja 会生成 Ninja 这个构建系统的构建规则。Ninja 是一个高性能,跨平台的构建系统,Linux、Windows、MacOS 上都可以用。
  • Ninja 可以从包管理器里安装,没有包管理器的 Windows 可以用 Python 的包管理器安装:
    • pip install ninja(有趣的事实:CMake 也可以通过 pip install cmake 安装……)
  • 事实上,MSBuild 是单核心的构建系统,Makefile 虽然多核心但因历史兼容原因效率一般。而 Ninja 则是专为性能优化的构建系统,他和 CMake 结合都是行业标准了。

image.png
image.png

Ninja 和 Makefile 简单的对比

性能上:Ninja > Makefile > MSBuild
Makefile 启动时会把每个文件都检测一遍,浪费很多时间。特别是有很多文件,但是实际需要构建的只有一小部分,从而是 I/O Bound 的时候,Ninja 的速度提升就很明显。然而某些专利公司的 CUDA toolkit 在 Windows 上只允许用 MSBuild 构建,不能用 Ninja(怕不是和 Bill Gates 有什么交易)
image.png
image.png