在 Bazel 的 macro 中调用的规则(比如 native.cc_library、native.genrule 等)在语义上并不是“顺序执行”的,因为 Bazel 本身是一个 声明式的构建系统,构建规则的执行顺序是由 依赖图(DAG) 决定的,而不是宏中代码的书写顺序。
🔍 具体来说:
✅ 宏中的语句是“顺序执行”的(在解释阶段)
宏是用 Starlark 写的普通函数,在 Bazel 解析 BUILD 文件的时候,宏会被调用执行,在这个阶段,它们确实是从上到下按顺序执行的。
也就是说:
def my_macro(name):
native.genrule(
name = name + "_a",
outs = ["a.txt"],
cmd = "echo A > $@",
)
native.genrule(
name = name + "_b",
outs = ["b.txt"],
cmd = "echo B > $@",
)
-
_a规则和_b规则都会被创建。 -
它们的定义顺序是
_a然后_b,这个顺序是解析顺序。
🚫 但执行顺序(build 时)不一定按这个顺序
除非你显式地在规则之间加上依赖:
def my_macro(name):
native.genrule(
name = name + "_a",
outs = ["a.txt"],
cmd = "echo A > $@",
)
native.genrule(
name = name + "_b",
outs = ["b.txt"],
srcs = [":" + name + "_a"], # 依赖 _a 的输出
cmd = "cat $(SRCS) > $@ && echo B >> $@",
)
这样 Bazel 才知道 _b 依赖 _a,执行时会先构建 _a 再构建 _b。
✳️ 总结
| 层面 | 是否顺序执行 | 说明 |
|---|---|---|
| 宏定义阶段(BUILD 解析时) | ✅ 是 | Starlark 本身是顺序执行的语言 |
| 构建执行阶段(bazel build) | ❌ 否 | Bazel 按依赖图决定执行顺序,宏中定义顺序无效 |
| 如何控制顺序 | ➕ 添加 deps=、srcs=、data= 明确依赖关系 |

2777

被折叠的 条评论
为什么被折叠?



