记录一次cmake_minimum_required的思考


cmake_minimum_required

问题起源

在编译 MyTinySTL 项目时遇到 CMake 错误:

CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 3.5 has been removed from CMake.

项目中的 CMakeLists.txt 第一行是:

cmake_minimum_required(VERSION 2.8)

而我的 CMake 版本是 4.0.2,CMake会模拟启用2.8版本的所有默认行为,禁用 2.8 之后的所有新策略,模拟CMake 2.8 的运行环境。

深入理解 cmake_minimum_required

cmake_minimum_required是CMake中很重要的且要放在第一行的一个命令。它的作用并不是简单的进行版本的检查,最初我误解了cmake_minimum_required作用,以为它只能声明项目能工作的最低cmake版本,实际上CMake通过策略来管理版本间的行为变化,每个策略包括:

  • 有一个唯一编号
  • 控制某个特定功能的旧行为和新行为
  • 每个CMake版本会引入新策略或修改旧策略

它也告诉CMake:

  1. 行为模式选择器:告诉 CMake 以哪个版本的行为模式解析脚本
  2. 策略控制器:启用或禁用特定版本的策略(policies)
  3. 兼容性承诺:承诺脚本与指定版本兼容

为什么高版本 CMake 不支持低版本?

这不是技术限制,而是有意设计

  • CMake 4.0 移除了对 3.5 以下版本的兼容代码
  • 减少维护负担,提高性能
  • 推动生态进步,淘汰过时实践

就像 Windows 11 不再支持 Windows 98 程序一样。

最佳实践

  1. 使用范围语法
cmake_minimum_required(VERSION 3.16...3.28)

相关构建系统知识扩展

cmake --build .make 的区别

cmake --build .是跨平台抽象命令,自动调用底层构建工具:

  • Linux/maxOS: make
  • Windows(MSVC): MSBuild
  • Windows(MinGW): mingw32-make
  • Ninja: ninja

windows下MSVC的优势

  1. 深度优化:PGO、向量化、CPU特定优化

MinGW Makefiles生成器

mkdir mingw-build
cd mingw-build
cmake -G "MinGW Makefiles"
mingw32-make

-G "MinGW Makefiles"固定名称,告诉 CMake 生成适用于 MinGW 的 Makefile。

Ninja 极速构建系统

它的特点是专注于构建速度

cmake -G Ninja ..
ninja # 自动启用CPU所有核心

常见的一些使用技巧

多级构建目录

MyTinySTL/
├── CMakeLists.txt
├── build-msvc/      # Visual Studio 构建
├── build-mingw/     # MinGW 构建  
├── build-ninja/     # Ninja 构建
└── build-debug/     # 调试版本

查看可用的生成器

cmake -G

跨平台的CMakeLists.txt写法

if (MSVC)
	add_compile_options(/W4 /WX)
elseif (MINGW OR CMAKE_COMPILER_IS_GNUCXX)
	# GCC/MinGW 设置
    add_compile_options(-Wall -Wextra -Werror)
endif()

性能优化

  • 编译速度:Ninja > Make > MSBuild
  • 跨平台一致性:MSVC > GCC/MinGW

学习心得

通过此次编译错误,重新学习了CMake的编译构建理论


文章作者: AllenMirac
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 AllenMirac !
  目录