
构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载导读endblock()是 CMake 3.25 起随block()命令一同引入的配套命令用于结束一组由block()开启的命令列表并移除该块创建的所有作用域变量、策略、诊断。本文以 Help/command/endblock.rst 为骨架结合block()官方文档、block 源码实现 与 RunCMake/block 测试集完整讲解endblock()的语法规则、作用域生命周期、参数约束、嵌套校验机制以及break()/continue()/return()的交互行为帮助你写出作用域隔离、行为可预期的 CMake 脚本。1. 基本语法与核心作用官方文档对endblock的定义只有一句话它结束block()中的一组命令并移除由block()创建的作用域。其语法形式为endblock()几个关键事实引入版本block()/endblock()均在 CMake 3.25 中新增见 Help/command/endblock.rst 与 Help/command/block.rst。不接受任何参数endblock()必须无参调用。源码中cmBlockFunctionBlocker::EndCommandSupportsArguments()返回falsecmFunctionBlocker.cxx 会检测到带有参数的endblock(...)并报错 A logical block closing on the line ... has unexpected arguments.Tests/RunCMake/block/EndWithArgument.cmake 正是针对该错误路径的测试。不能单独出现endblock()必须与block()配对使用。解析阶段会用嵌套栈校验配对关系详见第 4 节。2. 与 block() 的配对工作流程先记录、后回放block()与endblock()的协作机制是理解本命令的关键。按照 Help/command/block.rst 的说明block()与匹配的endblock()之间的所有命令只被记录、不会立即执行当endblock()被求值时记录的命令列表才在指定的作用域内被逐一调用之后block()创建的作用域被移除。这一记录–回放机制在源码中有非常清晰的体现cmBlockCommand.cxx 的Replay()遍历收集到的cmListFileFunction并逐一调用mf.ExecuteCommand(fn, status)从而在endblock()到达时真正执行块内命令回放期间会透传return()、break()、continue()以及致命错误/退出码状态详见第 5 节块内收集到的命令由 cmFunctionBlocker.cxx 的Functions向量暂存block()/endblock()的嵌套深度通过ScopeDepth计数器维护深度归零时移除函数拦截器并触发回放。因此endblock()表面上是结束标记实际承担了触发作用域内命令回放与作用域清理的双重职责。3. 作用域生命周期block 创建endblock 移除block()可以通过SCOPE_FOR指定要创建的作用域类型不指定时等价于block(SCOPE_FOR VARIABLES POLICIES DIAGNOSTICS)三种作用域与离开块时的行为如下表所示SCOPE_FOR 取值等价操作开启离开 block 时由 endblock 触发引入版本VARIABLES创建新的变量作用域变量作用域弹出块内新定义/修改的变量不污染外层3.25POLICIEScmake_policy(PUSH)自动cmake_policy(POP)恢复外层策略设置3.25DIAGNOSTICScmake_diagnostic(PUSH)自动cmake_diagnostic(POP)恢复诊断配置4.4见 Help/command/block.rst从源码实现看cmBlockCommand.cxx 的BlockScopePushPop会根据ScopeSet分别构造cmMakefile::VariablePushPop、PolicyPushPop、DiagnosticPushPop三个 RAII 助手类定义见 cmMakefile.h这些对象在cmBlockFunctionBlocker析构时自动析构从而在endblock()回放完成后统一弹出对应作用域。3.1 PROPAGATE把块内变量带回父作用域变量作用域默认会把块内改动隔离在外层若确实需要将某些变量带出去使用PROPAGATE选项set(var1 INIT1) set(var2 INIT2) set(var3 INIT3) block(PROPAGATE var1 var2) set(var1 VALUE1) unset(var2) set(var3 VALUE3) endblock() # 现在 var1 的值为 VALUE1var2 已解除定义var3 仍保持初始值 INIT3官方文档明确了两条规则见 Help/command/block.rstPROPAGATE等价于对每个列出的变量执行set(... PARENT_SCOPE)或unset(... PARENT_SCOPE)仅当block()创建了变量作用域时才能使用PROPAGATE否则报错。源码在 cmBlockCommand.cxx 中对应检查PROPAGATE cannot be specified without a new scope for VARIABLES。其底层实现位于 cmMakefile.cxx 的RaiseScope(std::vectorstd::string const)对每个变量若块作用域内仍处于定义状态则把值提升到父作用域否则在父作用域执行解除定义。cmBlockFunctionBlocker的析构函数cmBlockCommand.cxx在离开块时调用该RaiseScope因此PROPAGATE的效果在endblock()处生效。测试用例 Tests/RunCMake/block/Workflows.cmake 验证了块内 set PROPAGATE 回传、块内未列出的变量不污染外层的完整行为。4. 嵌套与配对校验让错误在解析期暴露block/endblock支持任意嵌套配对合法性在解析阶段即被检查。cmListFileCache.cxx 在解析命令时维护一个嵌套状态栈遇到block压栈NestingStateEnum::Block遇到endblock时若栈顶不是Block则返回出错上下文缺少匹配的block否则弹栈。对应测试覆盖了各种非法配对场景Tests/RunCMake/block/EndAlone.cmake孤立出现的endblock()EndMissing.cmake有block()但没有endblock()闭合EndWithArgument.cmakeendblock(END_ARG)带参数InvalidNesting1.cmake~InvalidNesting6.cmake与function/macro/foreach/while/if等嵌套结构交叉错配。运行时若在错误位置遇到endblock()cmFunctionBlocker.cxx 还会发出CMD_AUTHOR级别的诊断信息指明闭合行并说明存在意外参数。5. 与 break() / continue() / return() 的交互block()出现在foreach()或while()内部时break()与continue()可以在块内直接使用Help/command/block.rstwhile(TRUE) block() # ... # break() 会终止 while() 循环 break() endblock() endwhile()源码层面的处理在Replay()中回放块内命令时一旦检测到break或continue被调用立即终止回放并把对应状态向上传播cmBlockCommand.cxx。同样地return()在块内被调用时会先通过RaiseScope把return()的返回值变量提升到外层再向外传播返回状态cmBlockCommand.cxx。Tests/RunCMake/block/Workflows.cmake 分别用whilebreak、functionreturn、foreachcontinue三种组合验证了这一行为例如continue()会跳过块内其后的set(VAR${id} BAD${id})语句。6. 典型使用场景与建议临时作用域隔离在大型脚本中为局部计算开辟独立变量作用域避免临时变量泄漏到文件级/目录级作用域需要回传结果时用PROPAGATE显式列出变量名。策略临时调整block(SCOPE_FOR POLICIES)内临时设置某个策略endblock()后自动恢复无需手工cmake_policy(PUSH/POP)配对。诊断配置局部化CMake 4.4 起可结合SCOPE_FOR DIAGNOSTICS在块内局部调整诊断严格度离开块自动恢复。配合循环控制在foreach/while循环体中使用block()包裹逻辑仍可正常使用break()/continue()。7. 小结endblock()虽然只占一行、不接受参数但它承担着回放块内记录的命令、弹出block()创建的作用域、并触发PROPAGATE变量回传的收尾职责。理解它需要掌握三件事块内命令先记录、后回放的执行模型见 cmBlockCommand.cxx、作用域由 RAII 助手类管理的生命周期见 cmMakefile.h、以及解析期嵌套栈对配对合法性的保证见 cmListFileCache.cxx。配合 Tests/RunCMake/block/ 中的各类用例可以进一步验证边界行为。参见Help/command/block.rstblock()命令的完整选项SCOPE_FOR、PROPAGATE与示例Source/cmBlockCommand.cxxblock/endblock的函数拦截器与回放实现Source/cmFunctionBlocker.cxx拦截、深度计数、错误诊断与回放触发逻辑Help/command/return.rst、Help/command/cmake_policy.rst与endblock密切相关的控制流命令。赞分享构建工具开发工具CLI【免费下载链接】CMakeMirror of CMake upstream repository项目地址https://gitcode.com/gh_mirrors/cm/CMake点击查看免费下载相关推荐浏览器里解密加密音乐Unlock-Music 三步上手教程浏览器里解密加密音乐Unlock Music 三步上手教程 先说一个有点反常识的结论解密加密音乐文件你不用安装任何软件。Unlock Music 是一个完构建工具开发工具CLIkomorebi close-workspace 命令详解关闭并回收空工作区的正确姿势komorebi close workspace 命令详解关闭并回收空工作区的正确姿势 导读 close workspace 是 komorebi 窗口管理器桌面应用Linux 终端会话回放实战scriptreplay 命令详解linux-command 命令手册Linux 终端会话回放实战scriptreplay 命令详解linux command 命令手册 scriptreplay 是 Linux 上配合 sc文档教程上一篇Unleash REST API 设计规范URL 结构、响应契约与分页策略的工程实践指南下一篇mailcow-dockerized 中的 Adldap2 Group 模型实战LDAP 组的创建、成员查询与增删改全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考