news 2026/10/10 13:54:38

CMake 策略 CMP0106 详解:Documentation 模块移除与 VTK 专用构建逻辑的迁移指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CMake 策略 CMP0106 详解:Documentation 模块移除与 VTK 专用构建逻辑的迁移指南
  • 构建工具
  • 开发工具
  • CLI

【免费下载链接】CMake

Mirror of CMake upstream repository

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

CMake 策略 CMP0106 于 CMake 3.18 引入,宣布随 CMake 发行的Documentation模块被移除:该模块原本是 CMake 为 VTK 项目提供的文档构建支持机制,其缓存变量与依赖查找逻辑与 VTK 深度耦合。本文以 CMP0106.rst 为骨架,结合当前仓库中该策略的注册代码、include()命令的模块拦截实现以及模块本体源码,说明 OLD/NEW 两种行为的具体差异、策略的触发与警告路径,并给出面向普通项目的迁移与设置方法,帮助读者在升级 CMake 时正确处置include(Documentation)调用。

策略背景:一个为 VTK 量身定做的模块

Documentation模块最初并非通用工具,而是 CMake 为 VTK 项目提供文档构建支持而添加的机制,其内容专门针对 VTK 的文档框架做了调优。按照 CMP0106.rst 的说明,CMake 不再随自身发行这个带有"过时 VTK 模式"(now old VTK patterns)的模块,而是由 CMake 自己将其标记为废弃。

从仓库中 Modules/Documentation.cmake 的旧逻辑可以看到它的真实面貌:当BUILD_DOCUMENTATION选项开启后,模块会依次find_package()查找UnixCommands、Doxygen、Gnuplot、HTMLHelp、Perl、Wget等一系列与文档生成链条相关的工具,并定义DOCUMENTATION_HTML_HELP、DOCUMENTATION_HTML_TARZ等缓存选项——这些依赖集合正是围绕 VTK 的文档流水线设计的,对绝大多数普通项目毫无意义。

OLD 与 NEW 行为对比

策略的核心分歧在于include(Documentation)被调用时会发生什么:

行为效果
OLD模块正常加载:添加BUILD_DOCUMENTATION、DOCUMENTATION_HTML_HELP、DOCUMENTATION_HTML_TARZ等缓存变量,并查找 VTK 文档所依赖的包(Doxygen、Perl、Wget 等)
NEW模块被视为空模块:不添加任何缓存变量,不查找任何包,include(Documentation)实际不产生任何副作用

需要注意,策略文档中"NEW 行为是充当空模块"的表述,在实现层面体现为两层机制:

  1. include()层面的拦截:在 Source/cmIncludeCommand.cxx 中,Documentation被登记在DeprecatedModules映射表内,对应cmPolicies::CMP0106。当include(Documentation)解析到系统模块时(同一文件),若策略状态为NEW,模块文件路径会被置空(mfile = ""),即模块根本不会被加载,等价于空操作。
  2. 模块本体层面的防护:Modules/Documentation.cmake开头通过cmake_policy(GET CMP0106 ...)读取策略,若为NEW会直接message(FATAL_ERROR)拒绝执行,提示该逻辑应随使用它的项目一同分发,而非由 CMake 提供。

策略如何被触发:警告与未设置状态

CMP0106 在 Source/cmPolicies.h 中以WARN状态注册,版本为 3.18:

SELECT(POLICY, CMP0106, "The Documentation module is removed.", 3, 18, 0, WARN)

按照 STANDARD_ADVICE.rst 的通用规则:该策略由cmake_policy或cmake_minimum_required设置;若项目未显式设置,CMake 会发出警告并采用 OLD 行为。

在实际行为中,include()命令在策略处于WARN状态时会调用IssuePolicyWarning(见 Source/cmIncludeCommand.cxx)。而Modules/Documentation.cmake内部对未设置状态还有一处"VTK 特赦":如果检测到项目自身就是 VTK(CMAKE_PROJECT_NAME或PROJECT_NAME为VTK),则抑制警告,避免干扰 VTK 自身的构建;对非 VTK 项目则照常告警(Modules/Documentation.cmake)。

如何设置与迁移

方式一:通过cmake_minimum_required按版本启用

策略机制的设计原则是"按 CMake 版本批量设置",而不是逐个开关。在顶层CMakeLists.txt开头使用:

cmake_minimum_required(VERSION 3.18)

此时 CMake 会把 3.18 及之前引入的所有策略(含 CMP0106)设置为 NEW 行为。若要保留较低的最低版本、同时按策略上限启用新行为,可写成cmake_minimum_required(VERSION 3.10...3.18)形式,详见 cmake_minimum_required.rst 对<min>[...<policy_max>]语法的说明。

方式二:显式cmake_policy(SET)

需要局部或逐个控制时使用:

if(POLICY CMP0106) cmake_policy(SET CMP0106 NEW) endif()

相关命令的完整签名(SET、GET、PUSH/POP)见 cmake_policy.rst。注意cmake_policy作用于策略栈顶,include()和find_package()加载的脚本默认拥有独立策略作用域,除非显式指定NO_POLICY_SCOPE。

方式三:命令行缓存变量(不改项目文件)

用户在不修改项目的前提下,可在cmake命令行传入缓存变量压制警告:

cmake -DCMAKE_POLICY_DEFAULT_CMP0106=NEW ...

该做法与cmake -DCMAKE_POLICY_DEFAULT_CMP0990=OLD的通用形式一致,见 cmake-policies.7.rst 的"Transition Schedule"一节。

迁移建议:把 VTK 专用逻辑带回项目自身

CMP0106 给出的方向非常明确:文档构建这类与具体项目强相关的逻辑,"最好随使用它的项目一起分发,而不是放在 CMake 里"。对仍依赖旧行为的项目,建议把Modules/Documentation.cmake中的相关逻辑(BUILD_DOCUMENTATION选项、Doxygen/Perl/Wget 查找等)复制到项目自己的模块目录,通过CMAKE_MODULE_PATH引入,并移除对include(Documentation)的依赖。

OLD 行为的寿命:废弃时间线

正如 DEPRECATED.rst 所强调的,策略的OLD行为"按定义即已废弃",可能在未来版本中被移除。通用时间线(见 cmake-policies.7.rst):

  • 策略引入 2 年后,显式设置OLD的版本可能开始警告其将被移除;
  • 策略引入 6 年后,主版本号更高的 CMake 可能直接报错,拒绝继续使用OLD行为。

因此,长期维护的项目不应停留在OLD/警告静默阶段,而应尽早迁移到NEW行为或自维护文档模块。从当前仓库的 cmake-policies.7.rst 策略清单可见,CMP0106 与 CMP0107、CMP0108 等一同列于"CMake 3.18 引入的策略"分组中;同时该清单也展示了本仓库已演进至包含 CMake 4.x 时代策略的较新开发版本,CMP0106 的 OLD 行为正在逐步走向淘汰边缘。

常见问题速查

  • 为什么include(Documentation)现在会警告?因为策略未设置时默认走 OLD 并告警;设置NEW后模块不再加载。
  • 我是普通项目,用不到 VTK 文档,怎么处理?直接让项目版本不低于 3.18(cmake_minimum_required(VERSION 3.18)),或显式cmake_policy(SET CMP0106 NEW)。
  • 我是 VTK 或基于 VTK 的文档项目怎么办?若项目名恰为VTK可免于警告;否则把模块逻辑搬入项目自身,或临时设置OLD并规划迁移。
  • NEW行为下模块还会报 FATAL_ERROR 吗?通过include(Documentation)正常加载时,模块在NEW下根本不会被执行(被include()拦截为空);仅当模块文件被其他方式直接执行且策略为NEW时,其内部才会触发致命错误,这是模块自带的二次防护。

延伸阅读

  • 策略文档正文:Help/policy/CMP0106.rst
  • 模块源码(含 OLD 行为实现):Modules/Documentation.cmake
  • 模块文档入口:Help/module/Documentation.rst
  • 策略注册表(SELECT(POLICY, CMP0106, ...)):Source/cmPolicies.h
  • include()对废弃模块的拦截实现:Source/cmIncludeCommand.cxx
  • 策略机制总览与过渡时间线:Help/manual/cmake-policies.7.rst
  • 策略设置命令:Help/command/cmake_policy.rst、Help/command/cmake_minimum_required.rst
  • 构建工具
  • 开发工具
  • CLI

【免费下载链接】CMake

Mirror of CMake upstream repository

项目地址:https://gitcode.com/gh_mirrors/cm/CMake
点击查看免费下载
上一篇:Awesome-CV技能评分可视化:星级与进度条设计
下一篇:如何快速解决大模型下载速度慢?多源镜像终极加速指南

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 13:54:16

从 1.9 万到 6.4 万星:拆解 Archify 的增长曲线与引爆点

从 1.9 万到 6.4 万星&#xff1a;拆解 Archify 的增长曲线与引爆点 【免费下载链接】archify Turn any idea, plan, or codebase into a beautiful interactive diagram. An agent skill for Claude Code, Codex, and more. 项目地址: https://gitcode.com/GitHub_Trending/…

作者头像 李华
网站建设 2026/10/10 13:53:35

同叫 autoclip,两条技术路线:VAD 规则切分与 AI 语义切分谁更靠谱

同叫 autoclip&#xff0c;两条技术路线&#xff1a;VAD 规则切分与 AI 语义切分谁更靠谱 【免费下载链接】autoclip AutoClip&#xff5c;一个链接&#xff0c;一键出片。开源 AI 视频剪辑桌面工具&#xff0c;将播客、访谈、课程等长视频自动剪成短视频&#xff0c;生成字幕、…

作者头像 李华
网站建设 2026/10/10 13:51:27

Java超市货架管理系统:高并发扫码与库存实时同步实战

简介&#xff1a;本资源是一篇面向计算机专业本科生的毕业设计论文&#xff0c;聚焦超市货架商品管理系统的工程实践&#xff0c;适用于软件开发初学者、课程设计参考者及Java Web技术学习者。论文完整阐述了基于Java语言与Oracle数据库构建超市管理系统的全过程&#xff0c;涵…

作者头像 李华
网站建设 2026/10/10 13:50:01

Linux虚拟桌面显示协议落地:内核KMS、无头渲染与协议分层实战

简介&#xff1a;这是一份面向Linux系统开发者、云计算工程师及桌面云技术研究人员的专业文献&#xff0c;聚焦虚拟桌面显示协议在Linux平台下的实现路径。内容从Linux主流图形系统X Window System的X Server、X Protocol、X Client三层架构讲起&#xff0c;逐项解析直接X11协议…

作者头像 李华
网站建设 2026/10/10 13:45:20

UNet实现遥感图像语义分割:PyTorch毕业设计源码与踩坑实践

简介&#xff1a;一份基于UNet的遥感图像语义分割Python毕业设计项目&#xff0c;含可运行源码与配套论文&#xff0c;面向计算机、地理信息等专业学生&#xff0c;适用于毕业设计、课程设计及期末大作业。项目源码经本地编译运行&#xff0c;评审分达98分&#xff0c;难度适中…

作者头像 李华