☰
CMake build_name 命令全解析:为何被禁、如何迁移到 CMAKE_SYSTEM 与 CMAKE_<LANG>_COMPILER
2026/10/3 1:50:02 网站建设 项目流程
  • 构建工具
  • 开发工具
  • CLI

【免费下载链接】CMake

Mirror of CMake upstream repository

项目地址:https://gitcode.com/gh_mirrors/cm/CMake
点击查看免费下载

build_name是 CMake 历史上最早引入的辅助命令之一,用于生成"操作系统 + 编译器组合"的构建环境标识字符串。自 CMake 3.0 起该命令已被禁止调用(对应 CMake Policy CMP0036),并在 CMake 4.0 中被彻底移除。本文以 build_name 官方文档 为骨架,结合仓库源码与策略文档,完整讲解该命令的历史作用、语法、被禁原因、迁移方案与兼容性注意事项,帮助读者在维护老旧 CMake 项目时正确识别并改写这类调用。

一、命令速览:语法与作用

在 build_name 命令文档 中,命令的完整语法只有一行:

build_name(variable)

其语义是:将指定的变量设置为一个代表当前平台(操作系统)与编译器设置的字符串。例如,早期 CMake 脚本中常见这样的写法:

build_name(MY_BUILD_TAG) message(STATUS "Current build environment: ${MY_BUILD_TAG}")

该字符串通常用于构造构建输出目录名、日志前缀或发布包命名。但文档明确指出,这种"平台 + 编译器组合"信息如今已不再需要通过命令动态计算——它们已经作为标准变量暴露给所有 CMake 脚本:

  • CMAKE_SYSTEM:CMake 正在为之编译的目标操作系统组合名称;
  • CMAKE_CXX_COMPILER:C++ 编译器的完整路径(即 CMAKE_ _COMPILER 在LANG为CXX时的具体实例)。

因此文档给出的官方结论是:不要再用build_name,改用这两个变量即可。

二、历史背景:2001 年诞生的早期命令

为什么 CMake 曾需要这样一个命令?CMP0036 策略文档 给出了清晰的溯源:

This command was added in May 2001 to compute a name for the current operating system and compiler combination.

也就是说,build_name于2001 年 5 月加入 CMake,其设计目的就是为"当前操作系统 + 编译器组合"计算一个名字。在 CMake 的早期版本中,平台探测与编译器探测的结果尚未系统化地沉淀为脚本变量,开发者需要一个统一的入口来获取这类环境信息,于是build_name应运而生。

该命令随后长期处于"官方文档标注为不推荐使用(discouraged)"的状态——文档中记载 "The command has long been documented as discouraged",因为它所提供的能力逐渐被标准变量体系取代。随着CMAKE_SYSTEM与CMAKE_<LANG>_COMPILER系列变量的完善,保留该命令已无必要,最终被列入移除计划。

三、被禁用的机制:CMP0036 策略

命令被禁用,在 CMake 中是通过**策略(Policy)**机制实现的。CMP0036 的完整名称即 "Thebuild_namecommand should not be called"(不应再调用build_name命令)。

3.1 策略的时间线

阶段版本行为
命令引入2001-05计算操作系统与编译器组合名
策略引入 / 命令禁止CMake 3.0调用build_name时按策略处理:OLD允许调用,NEW直接报FATAL_ERROR
策略OLD行为移除CMake 4.0OLD行为被彻底删除,策略必须为NEW

CMP0036 策略文档使用的 REMOVED_COMMAND 模板 明确了两种行为模式:

  • OLD(旧行为):允许调用build_name命令;
  • NEW(新行为):一旦脚本调用build_name,CMake 直接抛出FATAL_ERROR终止配置。

同时,REMOVED_PROLOGUE 模板 记录了策略演进的后半段:CMake 4.0 起,OLD行为已被移除,策略必须通过cmake_minimum_required或cmake_policy显式设置为NEW,即任何对build_name的调用都会被视为致命错误。

3.2 源码中的策略注册与命令移除

在仓库源码中可以找到与这条策略链对应的两处关键实现:

  • 策略注册:在 Source/cmPolicies.h 中,CMP0036以如下形式注册,其标题文本与官方文档完全一致:
SELECT(POLICY, CMP0036, "The build_name command should not be called.", 3, ...)

其中3即策略引入版本 3.0,与文档一致。

  • 命令移除:在 Source/cmCommands.cxx 中,build_name已从命令表中移除,仅保留一条错误提示:
"build_name", "The build_name command has been removed; see CMP0036."

这从源码层面印证了:在现代 CMake 中,build_name已不是可执行的命令,而只是一个指向 CMP0036 的"路标"——当旧脚本试图调用它时,CMake 会引导用户查看该策略了解原因。

四、官方推荐的替代方案

文档给出的迁移路径非常明确:

Use ${CMAKE_SYSTEM} and ${CMAKE_CXX_COMPILER} instead.

即:用${CMAKE_SYSTEM}与${CMAKE_CXX_COMPILER}两个变量取代build_name的输出。

4.1 CMAKE_SYSTEM:目标操作系统组合名

CMAKE_SYSTEM 变量文档 给出了精确定义:

Composite name of operating system CMake is compiling for. This variable is the composite ofCMAKE_SYSTEM_NAMEandCMAKE_SYSTEM_VERSION, e.g.${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION}. IfCMAKE_SYSTEM_VERSIONis not set, then this variable is the same asCMAKE_SYSTEM_NAME.

要点归纳:

  • CMAKE_SYSTEM=CMAKE_SYSTEM_NAME与CMAKE_SYSTEM_VERSION的组合,形如Linux-5.15.0;
  • 若CMAKE_SYSTEM_VERSION未设置,则CMAKE_SYSTEM就等于CMAKE_SYSTEM_NAME(例如某些嵌入式目标平台);
  • 它是目标系统(CMake 正在为谁编译)的信息,而非运行 CMake 的宿主系统信息。

4.2 CMAKE_ _COMPILER:编译器路径

CMAKE_CXX_COMPILER是通用变量 CMAKE_ _COMPILER 的一个实例(LANG = CXX),保存 C++ 编译器的完整路径。同理还有CMAKE_C_COMPILER、CMAKE_Fortran_COMPILER等。当需要标识"编译器组合"时,按项目实际启用的语言取对应的<LANG>变量即可,而不仅仅局限于 C++。

五、实战迁移示例

下面给出一个从旧写法迁移到新写法的完整对照。

旧式写法(已失效,CMake 3.0+ 会报错,4.0+ 必报错):

build_name(MY_BUILD_TAG) message(STATUS "Build environment: ${MY_BUILD_TAG}") set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/${MY_BUILD_TAG}")

新式写法(官方推荐):

# 目标操作系统组合名,例如 Linux-5.15.0 set(PLATFORM_TAG "${CMAKE_SYSTEM}") # 编译器标识:CMake_<LANG>_COMPILER 的 C++ 实例 set(COMPILER_TAG "${CMAKE_CXX_COMPILER}") message(STATUS "Platform tag: ${PLATFORM_TAG}") message(STATUS "Compiler tag: ${COMPILER_TAG}") set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/${PLATFORM_TAG}-${CMAKE_CXX_COMPILER_ID}")

补充说明:

  • 若只需操作系统级标识,${CMAKE_SYSTEM}已完全覆盖build_name在这方面的能力;
  • 若需要编译器路径级标识,使用CMAKE_CXX_COMPILER(或对应语言的CMAKE_<LANG>_COMPILER);
  • 若希望得到更稳定、更易读的编译器家族标识(如GNU、Clang、MSVC),可以配合使用 CMAKE_ _COMPILER_ID 变量,而不是直接拼接路径。

六、兼容性与升级注意事项

对于仍然包含build_name调用的历史项目,需要注意以下几点:

  1. CMake 3.0 起默认行为已收紧:自 3.0 起,除非通过cmake_minimum_required(VERSION < 3.0)或cmake_policy(SET CMP0036 OLD)显式声明旧行为,否则调用build_name会触发FATAL_ERROR,配置直接中断。

  2. CMake 4.0 起 OLD 行为已移除:根据 REMOVED_PROLOGUE 模板,4.0 之后策略必须为NEW,不再存在任何"允许调用"的余地。也就是说,迁移不是可选项,而是硬性要求。

  3. 推荐做法是直接改写:与其靠cmake_policy(SET CMP0036 OLD)暂时绕过,不如按本文第五节的方式直接用${CMAKE_SYSTEM}与${CMAKE_CXX_COMPILER}重写脚本——变量取值由 CMake 内部探测逻辑保证一致性,结果稳定且跨版本可维护。

  4. 验证方式:改写后可在配置阶段打印验证:

message(STATUS "CMAKE_SYSTEM = ${CMAKE_SYSTEM}") message(STATUS "CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")

运行cmake -S . -B build后,对比输出与旧build_name曾生成的字符串,确认命名规则符合预期。

七、总结

build_name是 CMake 早期(2001 年)为"操作系统 + 编译器组合"命名而生的命令,其功能在现代 CMake 中已由标准变量体系完整取代。通过 CMP0036 策略,CMake 自 3.0 起禁止该命令(NEW行为直接FATAL_ERROR),自 4.0 起删除OLD行为、命令实现本身也从 Source/cmCommands.cxx 的命令表中移除。迁移路径简单明确:使用 CMAKE_SYSTEM 与 CMAKE_ _COMPILER 变量即可获得等价甚至更丰富的信息。维护旧项目时,建议直接改写脚本而非依赖策略回退,从根本上消除与未来 CMake 版本的兼容隐患。

  • 构建工具
  • 开发工具
  • CLI

【免费下载链接】CMake

Mirror of CMake upstream repository

项目地址:https://gitcode.com/gh_mirrors/cm/CMake
点击查看免费下载
上一篇:Helm工作流引擎:复杂业务流程自动化
下一篇:突破反爬!SeleniumBase v4.35.2重构CDP模式:5大场景实测防检测效果

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询