https://www.jayconrod.com/posts/110/writing-bazel-rules—repository-rules
0. Bazel基础
Bazel 构建目标主要有三个阶段:
- Loading
- Analysis
- Execution
在Loading阶段,Bazel读取和评估build文件,Bazel会构建目标及其依赖图。
在Analysis阶段,Bazel会评估目标graph,Analysis的输出是file-action graph(什么样的文件会执行什么操作),需要注意的是 rules本身不能直接执行输入/输出操作,仅仅是告诉Bazel构建过程应该是什么样的。
在Execution阶段,Bazel运行具体的actions来构建,Bazel会有不同的策略去运行actions。
1. 三个结构体
structs
providers
depsets
上面的三个数据结构用于在不同的rules之间传递信息,我们需要他们去收集依赖的相关信息。
Structs是Starlark的一种基本数据结构
my_value = struct(
foo = 12,
bar = 34,
)
使用的时候可以采用以下方法
print(my_value.foo + my_value.bar)
Provider 是一个named 的结构体,包含关于rule的信息。当provider被evaluated时,Rule implementation函数返回provider结构。 Providers可以被任何依赖于这个rule的东西读取到。
例如 cc_binary会返回一个 DefaultInfo
provider(这个是一个内置的provider)
Depsets
Bazel提供一个特殊目的的数据结构 depset,和其他的set一样,depset也是一系列唯一的values。
https://docs.bazel.build/versions/main/skylark/lib/depset.html
举个例子
这里定义一个新的provider LibraryInfo
会携带每个library和其相关依赖的信息
LibraryInfo = provider(
doc = "Contains information about a Go Library",
fileds = {
"info": """ A struct containing information about this library """,
"deps": "A depset of info structs for this library's dependencies",
},
)
然后在其他rule中使用这个LibraryInfo
go_library = rule(
_go_library_impl,
attrs = {
"srcs" : attr.label_list(
allow_files = [".go"],
),
"deps": attr.label_list(
proviers = [LibraryInfo],
),
}
)
下载抽取deb包
# deb包的具体属性
deb_packages = repository_rule(
attrs = _deb_packages_attrs,
implementation = _deb_packages_impl,
local = False,
)
其中, repository_ctx[ rctx]
https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#attr
context of repository rule 包含了以下信息
- attr [rctx.attr] 结构体,用户自定义具体内容
- delete [rctx.delete(path)] 删除某个文件或路径,返回bool
- download [rctx.download(url, output=’’,…)] 下载文件到某个path,返回一个结构体,包含文件的hash值
- download_and_extract [rctx.download_and_extract()] 下载文件并解压
- execute [rctx.execute(argument)] 执行command
- extract [rctx.extract(archive)]
- file [rctx.file(path)] 生成文件 ?
- name [rctx.name] 外部repository的name
- os [rctx.os]
- patch [rctx.patch(patch_file)] Apply a patch file to the root directory of external repository.
- read
- report_progress
- symlink
- template
- which
实例1 - 使用bazel安装一个deb包
使用repository_rule()方法安装一个包