尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CMake mark_as_advanced 命令:缓存变量高级属性管理与 CMP0102 策略详解

CMake mark_as_advanced 命令:缓存变量高级属性管理与 CMP0102 策略详解 构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载导读mark_as_advanced是 CMake 中用于管理缓存cache变量显示层级的核心命令它通过设置缓存条目的ADVANCED属性把变量标记为高级从而在ccmake、cmake-gui等图形界面中默认隐藏只有用户开启显示高级项时才可见。本指南以当前仓库中 Help/command/mark_as_advanced.rst 为骨架结合 Source/cmMarkAsAdvancedCommand.cxx 的实现与 Help/policy/CMP0102.rst 策略说明讲解完整语法、三种调用模式的行为差异、脚本模式下的特殊语义以及自 CMake 3.17 起由策略CMP0102引入的破坏性变更。读完本文你将能正确使用该命令整理自己的 CMake 项目缓存并理解旧版行为为何会导致find_*结果被意外清除。命令语法与核心语义命令的完整语法定义在官方文档中mark_as_advanced([CLEAR|FORCE] var1 ...)该命令的作用是设置指定缓存变量的 advanced/non-advanced高级/非高级状态对应底层实现中缓存条目的ADVANCED属性一个被标记为advanced高级的变量在所有 CMake 图形界面如cmake-gui、ccmake中默认不会显示除非用户打开 show advanced / 显示高级 选项在脚本模式script mode即cmake -P下advanced/non-advanced 状态没有任何效果——该属性只在 GUI 展示缓存变量时起作用。从源码看命令的实现位于 Source/cmMarkAsAdvancedCommand.cxx其处理逻辑可概括为解析可选关键字CLEAR或FORCE见下一节其余参数即为待操作的变量名依据CMP0102策略的取值OLD/NEW/WARN决定是否忽略未进入缓存cache的变量对于已存在的缓存条目在未显式覆盖未传CLEAR/FORCE且该条目已具有ADVANCED属性时保持原值不变否则写入新的ADVANCED属性值1表示高级、0表示非高级。若不传入任何变量实现会直接报错并返回失败源码中args.empty()分支输出called with incorrect number of arguments见 Source/cmMarkAsAdvancedCommand.cxx。三种调用模式默认、CLEAR 与 FORCE命令的行为由第一个可选关键字决定文档与实现完全一致调用形式关键字行为mark_as_advanced(var1 ...)无只新增不修改仅将新出现的变量标记为高级若变量已有 advanced/non-advanced 状态则保持不变mark_as_advanced(FORCE var1 ...)FORCE强制设为高级无论变量当前状态如何统一标记为高级mark_as_advanced(CLEAR var1 ...)CLEAR清除高级状态将高级变量改回非高级普通状态对应到 Source/cmMarkAsAdvancedCommand.cxx 的实现细节无关键字时内部overwrite falsevalue 1只有当缓存条目尚未设置ADVANCED属性时才写入传入FORCE时overwrite truevalue 1无条件覆盖为高级传入CLEAR时overwrite truevalue 0无条件覆盖为非高级。这解释了默认模式与FORCE/CLEAR的本质区别前者尊重变量既有状态幂等、不打扰用户已做的调整后者强制执行指定状态。写入属性使用SetCacheEntryProperty(variable, ADVANCED, value)见 Source/cmMarkAsAdvancedCommand.cxx而ADVANCED也是cmCacheManager::PersistentProperties中声明的持久化缓存属性之一见 Source/cmCacheManager.cxx意味着该标记会随CMakeCache.txt长期保存下次配置时依然生效。实战示例以下示例可在任意 CMake 项目的CMakeLists.txt中使用# 1) 将两个缓存变量标记为高级GUI 中默认隐藏 set(MY_INTERNAL_OPTION OFF CACHE BOOL 内部调试开关) set(MY_TOOL_PATH CACHE FILEPATH 内部工具路径) mark_as_advanced(MY_INTERNAL_OPTION MY_TOOL_PATH) # 2) 强制设为高级 mark_as_advanced(FORCE MY_INTERNAL_OPTION) # 3) 清除高级状态使其在 GUI 中恢复可见 mark_as_advanced(CLEAR MY_INTERNAL_OPTION) # 4) 混合使用一次处理多个变量 mark_as_advanced( MY_INTERNAL_OPTION MY_TOOL_PATH ANOTHER_CACHE_VARIABLE )搭配cmake-gui或ccmake使用时普通模式下这些变量不会出现在列表中切换为高级模式 / Advanced后即可看到并编辑它们。注意mark_as_advanced的使用对象必须是缓存变量通常由set(... CACHE ...)、option()或find_*命令创建对普通局部变量调用没有意义——自 3.17 起未在缓存中的变量会被直接忽略详见下文。脚本模式下状态无效的底层原因文档明确指出脚本模式script mode下 advanced 状态无效。原因从架构上即可理解ADVANCED是缓存条目的属性而缓存CMakeCache.txt只在**配置阶段configure**被创建和维护cmake -P script.cmake运行时不读写工程缓存文件。因此该命令在脚本模式中最多只对内存中的状态做无意义修改GUI 隐藏逻辑完全不参与。从源码结构看判断是否显示的逻辑位于 GUI 前端例如 Source/CursesDialog/cmCursesMainForm.cxx 通过GetCacheEntryPropertyAsBool(entry.GetValue(), ADVANCED)过滤高级条目与命令执行器是解耦的这也印证了状态只对 GUI 展示有意义的结论。常见搭配find_* 结果与 option 变量在实际工程中mark_as_advanced最常见的两个使用场景隐藏find_*命令生成的辅助变量如find_path、find_library、find_package产生的XXX_LIBRARY、XXX_INCLUDE_DIR等通常对普通用户属于内部细节项目作者会统一mark_as_advanced(...)隐藏减少 GUI 噪音隐藏仅供维护者使用的option()开关例如实验性功能开关、内部构建参数等。例如find_package(Foo REQUIRED) mark_as_advanced(FOO_LIBRARY FOO_INCLUDE_DIR)值得注意早期 CMake 中如果某个find_*结果变量只在局部作用域local scope存在对其调用mark_as_advanced会在旧策略行为下产生副作用——详见下一节。CMP0102 策略3.17 起的破坏性变更mark_as_advanced的行为在 CMake 3.17 发生了重要变化由策略CMP0102控制详见 Help/policy/CMP0102.rst自 3.17 起mark_as_advanced不再为不存在的变量创建缓存条目。3.16 及以前的旧行为OLD在 CMake 3.16 及更早版本中若变量未定义或仅为局部定义mark_as_advanced会自动创建一个类型为UNINITIALIZED、无值的空缓存条目。当后续find_path或其他find_*命令再次运行时会命中这个未定义缓存条目并将其设置为空字符串值——而缓存机制的工作方式会在过程中删除局部变量从而把只存在于局部作用域的find_*结果全部清空。这正是旧行为容易导致 find 结果莫名丢失 的经典陷阱。源码中对这一历史行为的还原可见 Source/cmMarkAsAdvancedCommand.cxx当策略为OLD且变量不在缓存中时通过AddCacheEntry(variable, ..., cmStateEnums::UNINITIALIZED)创建占位条目并将overwrite置真。3.17 及以后的新行为NEW新行为下凡是不在缓存中的变量一律被忽略不再创建任何空缓存条目见 Source/cmMarkAsAdvancedCommand.cxx 的ignoreVariable true分支。这从根本上消除了上述副作用。迁移注意事项策略默认状态为WARN警告当以旧行为调用且变量不在缓存中时会提示Policy CMP0102 is not set: The variable named ... is not in the cache...并建议运行cmake --help-policy CMP0102查看细节或使用cmake_policy命令显式设置策略见 Source/cmMarkAsAdvancedCommand.cxx新项目应直接在CMakeLists.txt顶部声明策略例如cmake_minimum_required(VERSION 3.17) # 或显式设置 cmake_policy(SET CMP0102 NEW)如果工程必须兼容 3.16 及以下版本且存在先mark_as_advanced后find_*的调用顺序需要重新审视代码确保mark_as_advanced的变量确实已存在于缓存中先find_*再标记或对find_*结果显式set(... CACHE ...)后再标记。测试佐证仓库中 Tests/RunCMake/CMP0102 目录专门覆盖该策略的四种场景RunCMakeTest.cmake依次运行CMP0102-OLD、CMP0102-NEW、CMP0102-WARN、CMP0102-WARN-DefaultCMP0102-Common.cmake 中对未定义变量执行mark_as_advanced(CMP0102_TEST_VARIABLE)CMP0102-OLD.cmake 断言OLD 行为下存在类型为UNINITIALIZED的缓存条目CMP0102-NEW.cmake 断言NEW 行为下不存在任何缓存条目get_property(... PROPERTY TYPE SET)为假即通过。该测试直接验证了本文描述的 OLD/NEW 行为差异是阅读实现之外最可靠的证据。与缓存属性和 GUI 的联动理解ADVANCED属性在系统中的位置有助于把握命令的完整影响面持久化ADVANCED与MODIFIED等一同列在cmCacheManager::PersistentProperties见 Source/cmCacheManager.cxx写入后会固化在CMakeCache.txt中GUI 过滤ccmake前端在渲染缓存条目列表时对普通模式跳过ADVANCED为真的条目仅在高级模式下全部展示见 Source/CursesDialog/cmCursesMainForm.cxx命令行缓存注入CMake 解析命令行-DVAR:typevalue参数时也可以通过SetCacheEntryProperty(..., ADVANCED, 1)将环境变量注入的条目直接标为高级如CMAKE_POLICY_VERSION_MINIMUM的处理见 Source/cmake.cxx这展示了一条与mark_as_advanced等价的属性写入路径。小结与最佳实践用mark_as_advanced隐藏缓存变量而非普通变量它只影响 GUI 展示不影响配置结果本身默认形式不加关键字尊重既有状态适合在模块/子目录中温柔地隐藏变量FORCE/CLEAR用于需要强制统一状态的场景脚本模式cmake -P下该命令无实际效果自 3.17 起策略CMP0102未入缓存变量会被忽略务必先创建缓存条目再标记避免旧行为中find_*结果被空缓存条目清空的隐患若需要兼容旧版本显式cmake_policy(SET CMP0102 NEW)可同时获得新行为并抑制 WARN 告警。相关资源官方命令文档Help/command/mark_as_advanced.rst策略文档Help/policy/CMP0102.rst命令实现Source/cmMarkAsAdvancedCommand.cxx、Source/cmMarkAsAdvancedCommand.h策略测试Tests/RunCMake/CMP0102赞分享构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载相关推荐DLSS Swapper完整教程免费升级或回退游戏DLSS版本不用等官方更新DLSS Swapper完整教程免费升级或回退游戏DLSS版本不用等官方更新 DLSS Swapper是一款免费开源的Windows工具帮你下载、管理和切桌面应用gh_mirrors/api1/api 缓存机制详解Cache 命令与 UrlGenerator 缓存策略gh_mirrors/api1/api 缓存机制详解Cache 命令与 UrlGenerator 缓存策略 在现代 API 开发中缓存机制是提升系统性能的关后端API网关sorl-thumbnail 管理命令详解清理与重建缩略图缓存sorl thumbnail 管理命令详解清理与重建缩略图缓存 前言 sorl thumbnail 是一个强大的 Django 缩略图生成库它能够自动处理图上一篇Druid字体Fallback策略确保文本显示的无缝体验下一篇QUANTAXIS 常见问题全解析从安装、数据获取到回测、实盘与部署运维的排障实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表