ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CMake build_name 命令全解析:为何被禁、如何迁移到 CMAKE_SYSTEM 与 CMAKE_<LANG>_COMPILER

CMake build_name 命令全解析:为何被禁、如何迁移到 CMAKE_SYSTEM 与 CMAKE_<LANG>_COMPILER 构建工具开发工具CLI【免费下载链接】CMakeMirror 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_SYSTEMCMake 正在为之编译的目标操作系统组合名称CMAKE_CXX_COMPILERC 编译器的完整路径即 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行为被彻底删除策略必须为NEWCMP0036 策略文档使用的 REMOVED_COMMAND 模板 明确了两种行为模式OLD旧行为允许调用build_name命令NEW新行为一旦脚本调用build_nameCMake 直接抛出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_SYSTEMCMAKE_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调用的历史项目需要注意以下几点CMake 3.0 起默认行为已收紧自 3.0 起除非通过cmake_minimum_required(VERSION 3.0)或cmake_policy(SET CMP0036 OLD)显式声明旧行为否则调用build_name会触发FATAL_ERROR配置直接中断。CMake 4.0 起 OLD 行为已移除根据 REMOVED_PROLOGUE 模板4.0 之后策略必须为NEW不再存在任何允许调用的余地。也就是说迁移不是可选项而是硬性要求。推荐做法是直接改写与其靠cmake_policy(SET CMP0036 OLD)暂时绕过不如按本文第五节的方式直接用${CMAKE_SYSTEM}与${CMAKE_CXX_COMPILER}重写脚本——变量取值由 CMake 内部探测逻辑保证一致性结果稳定且跨版本可维护。验证方式改写后可在配置阶段打印验证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【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载相关推荐CMake 非目标指令Non-Target Directives为何被官方劝阻从 add_* 到 target_* 命令的设计取舍与迁移实践CMake 非目标指令Non Target Directives为何被官方劝阻从 add_ 到 target_ 命令的设计取舍与迁移实践 本文围绕 CMa构建工具开发工具CLI为什么 LaravelCollective HTML 被废弃以及如何迁移到 Spatie Laravel HTML为什么 LaravelCollective HTML 被废弃以及如何迁移到 Spatie Laravel HTML LaravelCollective HTMSpring SimpleCommandLineArgsParser 源码解析命令行参数如何被解析为属性源Spring SimpleCommandLineArgsParser 源码解析命令行参数如何被解析为属性源 导读 本文聚焦 Spring 框架 org.spr文档教程知识库上一篇Helm工作流引擎复杂业务流程自动化下一篇突破反爬SeleniumBase v4.35.2重构CDP模式5大场景实测防检测效果创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表