Buck 仓库中的 bazel-skylib:Skylark 构建规则标准库与 skylark_library 规则解析
开发工具构建工具【免费下载链接】buckA fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.项目地址https://gitcode.com/gh_mirrors/bu/buck点击查看免费下载Skylib 是一套面向 Bazel/Skylark 构建规则开发的“标准库”提供集合、字典、文件路径、select 选择、shell 转义和单元测试等工具函数。本文基于 Buck 仓库中 vendored 的 bazel-skylib 快照 及其模块源码讲解其模块组织方式、各模块的实际 API、聚合规则skylark_library的实现原理以及它在 Buck 自身 Bazel 迁移规则中的真实用途读完后可独立为.bzl规则文件选择和使用这些标准函数。Skylib 的定位为什么 Buck 仓库里有一份 Bazel 库README.md 的开篇定义Skylib 是“a standard library that provides functions useful for manipulating collections, file paths, and other features that are useful when writing custom build rules in Bazel”——即一套专门服务于自定义构建规则编写的函数库而非常规构建产物库。README 同时明确提示该库处于早期开发阶段API 在此期间可能发生变化。结合仓库内的其他文件可以确认它的来源与用途README.facebook 说明该目录是从bazelbuild/bazel-skylib上游仓库整体拷贝并“as-is”展开的属于第三方 vendored 代码WORKSPACE 中声明workspace(name bazel_skylib)即它作为独立 Bazel 工作区时暴露的仓库名从 Buck 自身的构建文件来看它在被加载时使用了buck_bazel_skylib这一仓库名例如 tools/build_rules/module_rules.bzl 与 tools/build_rules/java_rules.bzl 均有load(buck_bazel_skylib//lib:collections.bzl, collections)programs/BUCK 中则有load(buck_bazel_skylib//lib:dicts.bzl, dicts)。也就是说Buck 仓库把 Skylib 作为外部依赖external repository引入供其 Bazel 迁移用的tools/build_rules/*.bzl规则集调用这正是 Skylib 设计初衷“支撑自定义规则开发”的落地场景。模块体系.bzl文件即“模块”lib.bzl作为索引README 定义了 Skylib 的核心组织约定lib/目录下的每个.bzl文件定义一个“模块”module——一个struct内含一组相关函数和其他符号可作为单个单元被加载顶层文件lib.bzl充当索引index供其他模块从中统一导入使用方式是load(bazel_skylib//:lib.bzl, ...)后通过点号访问 struct 字段。README 给出的示例load(bazel_skylib//:lib.bzl, paths, shell) p paths.basename(foo.bar) s shell.quote(p)对照实际源码每个模块都严格遵循“私有实现 公开 struct 导出”的模式。以 lib/collections.bzl 为例collections struct( after_each _after_each, before_each _before_each, uniq _uniq, )私有函数以下划线命名_after_each等仅在文件内部可见调用方通过collections.uniq(...)这样的命名空间访问公开 API。README 中“编写新模块”一节正是这一约定的规范化描述详见后文。需要说明的一个事实细节当前快照中的 lib.bzl 仅包含版权头和一行 docstringIndex from which multiple modules can be loaded.并未内联任何load语句。实际的聚合工作由根目录 BUILD 中的skylark_library(name lib, ...)目标承担其deps列出了全部模块//lib:collections、//lib:dicts、//lib:paths、//lib:selects、//lib:sets、//lib:shell、//lib:structs、//lib:unittest。README 的“List of modules”列出的是 collections、dicts、paths、selects、sets、shell、unittest 七个模块而lib/目录中实际还存在 structs.bzl并被根 BUILD 的聚合目标依赖但未被 README 列入清单——这印证了 README 中“API 可能变动”的版本提示引用时以实际文件为准。核心模块 API 与实现解析以下逐个模块给出本快照中实际可用的函数及实现要点路径均相对于仓库根目录。collections序列操作lib/collections.bzl 导出三个函数collections.after_each(separator, iterable)在每个元素之后插入分隔符返回新列表collections.before_each(separator, iterable)在每个元素之前插入分隔符collections.uniq(iterable)利用字典推导式{element: None for element in iterable}去重要求元素可哈希。uniq的实现第 49-60 行展示了典型的 Bazel/Skylark 技巧——Skylark 语言没有内置集合类型用 dict 的键唯一性模拟 set 去重且保持首次出现顺序。dicts字典合并lib/dicts.bzl 只导出一个函数dicts.add(*dictionaries)返回包含所有入参字典条目的新 dict同键时参数列表中靠后的字典覆盖靠前的。其 docstring 特别说明设计动机是“支持零个或多个参数”——零参数返回空字典单参数等价于拷贝从而满足算术恒等律让调用方无需为输入数量写特判。这正是 Buck 的 programs/BUCK 加载它来合并字典配置的用途所在。paths文件路径操作功能最重的模块lib/paths.bzl 是本快照中最大的模块约 236 行提供 8 个函数全部针对Unix 风格分隔符——模块头部注释明确声明不支持 Windows 反斜杠路径或盘符函数行为要点basename(p)p.rpartition(/)[-1]取文件部分p以斜杠结尾时返回空串与 Pythonos.path.basename一致而与 Unixbasename命令不同dirname(p)取不含 basename 的前缀并像os.path.dirname一样去掉末尾连续斜杠无前缀时返回分隔符本身is_absolute(path)path.startswith(/)join(path, *others)模拟 POSIX 下os.path.join任一后续组件为绝对路径时丢弃之前所有组件normalize(path)模拟os.path.normpath空路径返回.、删除.段、折叠多余斜杠、处理..段相对路径保留前导..relativize(path, start)返回path相对于祖先路径start的部分因无法访问文件系统若path不在start之下会直接fail报错而非向上回溯replace_extension(p, new_extension)替换扩展名无扩展名时追加新扩展名split_extension(p)拆分为(root, ext)元组恒有root ext pbasename 前导点不计为扩展点故split_extension(.bashrc)返回(.bashrc, )其中normalize第 96-149 行用栈式遍历逐段处理..并保留了“单双前导斜杠原样、三个及以上折叠为一个”的 POSIX 语义relativize第 151-186 行则通过逐段 zip 比较前缀校验“path 必须位于 start 之下”。这些行为与tests/paths_tests.bzl280 行全库最大的测试文件中的用例一一对应。selects支持 OR 键的 select()lib/selects.bzl 提供selects.with_or(input_dict)与selects.with_or_dict(input_dict)with_or是原生select()的替代品键除了普通形式//foo:config1还允许元组形式(//foo:config1, //foo:config2)表示“任一命中即可”最终被展开为多个同值键with_or_dict返回展开后的 dict 本体便于 Skylark 宏检查select()内容原生select()的结果无法直接检查实现上会校验同一 config setting 标签不得在输入中出现多次重复时直接fail(key %s appears multiple times % ...)。sets 与 shell集合与 shell 转义lib/sets.bzl137 行提供以 dict 模拟集合的运算函数对应测试为 tests/sets_tests.bzllib/shell.bzl 导出两个函数shell.quote(s)单引号包裹并将内部单引号替换为\\即标准 POSIX shell 转义法实现仅一行 s.replace(, \\) shell.array_literal(iterable)生成可直接嵌入 shell 脚本的数组字面量例如shell.array_literal([a, b, c])得到(a b c)所有元素一律加引号以保证安全。这两个函数在编写genrule的cmd或sh_binary包装脚本时是拼接安全命令行的常用工具。structs 与 unittest结构转换与规则级单测lib/structs.bzl 的structs.to_dict(s)用dir(s)枚举字段并移除to_json/to_proto两个内置方法后构造 dict用于把 struct 转为可迭代的数据结构lib/unittest.bzl262 行导出两个模块unittest声明与定义单元测试与asserts断言函数。其核心unittest.make(impl)第 24-76 行把实现函数包装成_skylark_testable True且test True的 rule并从str(impl)中解析函数名用于测试输出用法模式为def _your_test(ctx): env unittest.begin(ctx) # 断言语句 unittest.end(env) your_test unittest.make(_your_test)docstring 同时提醒测试规则名必须以_test结尾。该模块还load(:sets.bzl, sets)是库内模块互相依赖的实例。skylark_library聚合.bzl的规则与 ProviderREADME 最后一节介绍skylark_library.bzl规则其完整实现见 skylark_library.bzl。该规则用于“聚合一组 Skylark 文件及其依赖供测试目标和文档生成使用”。规则定义第 46-59 行skylark_library rule( implementation _skylark_library_impl, attrs { srcs: attr.label_list(allow_files [.bzl]), deps: attr.label_list( allow_files [.bzl], providers [[SkylarkLibraryInfo]], ), }, )srcs本目标直接包含的.bzl文件deps依赖的其他skylark_library目标要求提供SkylarkLibraryInfo。实现逻辑第 26-44 行以depset(ctx.files.srcs, order postorder)起步累加各依赖的文件集然后同时返回DefaultInfofiles与runfiles都填充全部文件和自定义 providerSkylarkLibraryInfosrcs与transitive_srcs两个字段。源码注释解释了双重填充的意图全部依赖文件同时出现在files与runfiles中保证skylark_library既可以被其他程序作为data引用也可以出现在genrule()的tools里。docstring 中的标准用法示例第 60-109 行展示了在一个含checkstyle/、lua/子包的工作区里如何为各子包声明skylark_library目标load(buck_bazel_skylib//:skylark_library.bzl, skylark_library) skylark_library( name lua-rules, srcs [lua.bzl, luarocks.bzl], )在 Skylib 自身的 BUILD 中该规则被用于两个目标lib聚合索引入口deps 为全部 8 个模块和skylark_library本身每个模块在 lib/BUILD 中也有各自的skylark_library目标如unittest依赖:sets与源码中的load关系一致。此外两个 BUILD 都声明了testonly True的test_depsfilegroup供规则测试收集文件。测试组织与“编写新模块”流程tests/目录为每个模块配备同名测试文件collections_tests.bzl、paths_tests.bzl、shell_tests.bzl 等全部基于unittest模块编写与模块一一对应——这是 Skylib 对“每个模块必须带单测”约定的直接体现。README 的“Writing a new module”一节给出完整的模块新增流程与库内现有代码完全吻合在lib/下新建.bzl文件在文件内以下划线前缀私有方式定义函数或常量等符号创建导出的模块 struct把公开名映射到私有实现。README 的示例def _manipulate(): ... things struct( manipulate_manipulate, )在lib.bzl中加一行load(bazel_skylib//lib:things.bzl, things)使其可从索引访问注意按前文所述本快照中该索引职责已由根 BUILD 的skylark_library(name lib)目标承担实际维护时应同步更新该deps列表调用方即可load(bazel_skylib//:lib.bzl, things)后things.manipulate()使用在tests/目录为模块补充单元测试。适用前提与使用边界版本边界本库是上游早期快照版权头 2017 年README 明确 API 可能变化例如 README 模块清单未包含structs而lib.bzl索引文件仅有 docstring 无内联 load。引用时以仓库内实际文件为准平台边界paths模块仅支持 Unix 风格路径分隔符见 lib/paths.bzl 模块头注释语言边界全部函数运行于 Bazel 的 Skylark 环境不能直接用于普通 Python 或 Buck 的 Python DSL 中在 Buck 中的角色它是 Buck 仓库 Bazel 迁移规则集tools/build_rules/的外部依赖通过buck_bazel_skylib仓库名加载lib/collections.bzl、lib/dicts.bzl等模块而非 Buck 构建流程本身的组成部分。综上bazel-skylib 以“模块 struct 索引聚合 skylark_library 依赖管理 逐模块单测”的完整范式为在 Buck 这类大型构建系统中编写和维护可复用的 Skylark 规则提供了标准函数基座与工程化模板。赞分享开发工具构建工具【免费下载链接】buckA fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.项目地址https://gitcode.com/gh_mirrors/bu/buck点击查看免费下载相关推荐bazel_rules_mongo 接入指南在 Bazel 仓库间复用 MongoDB 构建规则的 Bzlmod 模块实践bazel_rules_mongo 接入指南在 Bazel 仓库间复用 MongoDB 构建规则的 Bzlmod 模块实践 导读 bazel_rules_mo数据库文档数据库后端PyTorch 仓库协作规范深度解析AGENTS.md 中的构建、测试、Lint 与 ghstack 实战规则PyTorch 仓库协作规范深度解析AGENTS.md 中的构建、测试、Lint 与 ghstack 实战规则 PyTorch 仓库根目录下的 AGENTS.人工智能机器学习深度学习分布式训练模型编译COSMIC 桌面环境从零到上手10 分钟完整装好并跑通日常使用COSMIC 桌面环境从零到上手10 分钟完整装好并跑通日常使用 你是不是也遇到过这种情况正干着活窗口卡住不动alttab 没反应重启一下桌面还是有操作系统桌面应用上一篇UKB_RAP 项目模块化使用指南下一篇wx-livespy微信视频号直播数据实时捕获与分析引擎创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

RT-Thread LPC408x 板级支持包(BSP)使用指南:编译、烧写与驱动配置

RT-Thread LPC408x 板级支持包(BSP)使用指南:编译、烧写与驱动配置

操作系统嵌入式物联网嵌入式OSRTOS 【免费下载链接】rt-thread RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/ 项目地址: https://gitcode.com/gh_mirrors/rt/rt-thread 点击查看 免费下载 RT-Thre…

2026/9/25 3:07:35 阅读更多 →
用 AI 小说生成器完整写出一部长篇小说:从安装到定稿

用 AI 小说生成器完整写出一部长篇小说:从安装到定稿

用 AI 小说生成器完整写出一部长篇小说:从安装到定稿 【免费下载链接】AI_NovelGenerator 使用ai生成多章节的长篇小说,自动衔接上下文、伏笔 项目地址: https://gitcode.com/GitHub_Trending/ai/AI_NovelGenerator AI_NovelGenerator 是一个基于…

2026/9/25 3:07:35 阅读更多 →
MikroORM 双向关系传播(Propagation)机制详解:让关系两侧始终保持同步

MikroORM 双向关系传播(Propagation)机制详解:让关系两侧始终保持同步

后端 【免费下载链接】mikro-orm TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, MS SQL Server, PostgreSQL and SQLite/libSQL databases. 项目地址: https://gitcode.com/gh_mir…

2026/9/25 3:07:35 阅读更多 →

最新新闻

从 Codex CLI 到知识库:TaoToken 统一 Key 驱动的 AI 代理个人知识管理全流程

从 Codex CLI 到知识库:TaoToken 统一 Key 驱动的 AI 代理个人知识管理全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:58:52 阅读更多 →
Python寒假作业实战指南:从环境搭建到代码调试全流程

Python寒假作业实战指南:从环境搭建到代码调试全流程

拿到“Python第一次作业(寒假)”这个标题,我第一反应是想起自己当年第一次提交Python作业的样子——表面上是写几段代码,实际上一大半时间都耗在装环境、调报错、纠结“为什么输出和我想要的不一样”上面。这篇文章就是给同样在寒…

2026/9/25 4:58:52 阅读更多 →
STM32 I2C CubeMX配置四大致命陷阱与信号完整性避坑指南

STM32 I2C CubeMX配置四大致命陷阱与信号完整性避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:58:52 阅读更多 →
树莓派4B变身AI牛马:8GB内存跑本地大模型的实践与避坑指南

树莓派4B变身AI牛马:8GB内存跑本地大模型的实践与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:58:52 阅读更多 →
OpenClaw驱动SolidWorks二次开发:自然语言建模与自动化导出实战

OpenClaw驱动SolidWorks二次开发:自然语言建模与自动化导出实战

最近我把 OpenClaw 这个本地 AI Agent 框架和 SolidWorks 的二次开发链路打通了,现在能做到用自然语言直接驱动一部分建模、改参和导出操作。这套组合的定位不是拿 AI 替代 CAD 软件,而是让 AI 当“一个能听懂人话的调度员”,把重复的 API 调…

2026/9/25 4:58:52 阅读更多 →
深入理解 Sinon 的 `spyCall.firstArg`:读取单次调用首个参数的正确姿势

深入理解 Sinon 的 `spyCall.firstArg`:读取单次调用首个参数的正确姿势

测试开发工具 【免费下载链接】sinon Test spies, stubs and mocks for JavaScript. 项目地址: https://gitcode.com/gh_mirrors/si/sinon 点击查看 免费下载 spyCall.firstArg 是 Sinon 中 spy call 对象的一个核心只读属性,用于获取某一次函数调用传入…

2026/9/25 4:57:52 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →