您如何 运行 Bazel 规则中其他规则的可执行文件?
How can you run the executables of other rules within a Bazel rule?
假设我有一个自定义规则,my_object
。看起来像:
my_object(
name = "foo",
deps = [
//services/image-A:push,
//services/image-B:push,
]
)
其中 deps
中的标签是 rules_docker
的 container_push
规则。
我希望能够 bazel run //:foo
并将 Docker 图像推送到 deps
列表中。我该怎么做呢?
这似乎是一种特殊情况,通常只是想 运行 自定义规则的可执行文件中的其他规则的可执行文件。
这里要做的是让my_object
输出一个执行其他可执行文件的可执行文件。
考虑这个例子:
def _impl1(ctx):
ctx.actions.write(
output = ctx.outputs.executable,
is_executable = True,
content = "echo %s 123" % ctx.label.name)
return DefaultInfo(executable = ctx.outputs.executable)
exec_rule1 = rule(
implementation = _impl1,
executable = True,
)
def _impl2(ctx):
executable_paths = []
runfiles = ctx.runfiles()
for dep in ctx.attr.deps:
# the "./" is needed if the executable is in the current directory
# (i.e. in the workspace root)
executable_paths.append("./" + dep.files_to_run.executable.short_path)
# collect the runfiles of the other executables so their own runfiles
# will be available when the top-level executable runs
runfiles = runfiles.merge(dep.default_runfiles)
ctx.actions.write(
output = ctx.outputs.executable,
is_executable = True,
content = "\n".join(executable_paths))
return DefaultInfo(
executable = ctx.outputs.executable,
runfiles = runfiles)
exec_rule2 = rule(
implementation = _impl2,
executable = True,
attrs = {
"deps": attr.label_list(),
},
)
BUILD.bazel
:
load(":defs.bzl", "exec_rule1", "exec_rule2")
exec_rule1(name = "foo")
exec_rule1(name = "bar")
exec_rule2(name = "baz", deps = [":foo", ":bar"])
然后运行它:
$ bazel run //:baz
INFO: Analyzed target //:baz (4 packages loaded, 19 targets configured).
INFO: Found 1 target...
Target //:baz up-to-date:
bazel-bin/baz
INFO: Elapsed time: 0.211s, Critical Path: 0.01s
INFO: 0 processes.
INFO: Build completed successfully, 6 total actions
INFO: Build completed successfully, 6 total actions
foo 123
bar 123
假设我有一个自定义规则,my_object
。看起来像:
my_object(
name = "foo",
deps = [
//services/image-A:push,
//services/image-B:push,
]
)
其中 deps
中的标签是 rules_docker
的 container_push
规则。
我希望能够 bazel run //:foo
并将 Docker 图像推送到 deps
列表中。我该怎么做呢?
这似乎是一种特殊情况,通常只是想 运行 自定义规则的可执行文件中的其他规则的可执行文件。
这里要做的是让my_object
输出一个执行其他可执行文件的可执行文件。
考虑这个例子:
def _impl1(ctx):
ctx.actions.write(
output = ctx.outputs.executable,
is_executable = True,
content = "echo %s 123" % ctx.label.name)
return DefaultInfo(executable = ctx.outputs.executable)
exec_rule1 = rule(
implementation = _impl1,
executable = True,
)
def _impl2(ctx):
executable_paths = []
runfiles = ctx.runfiles()
for dep in ctx.attr.deps:
# the "./" is needed if the executable is in the current directory
# (i.e. in the workspace root)
executable_paths.append("./" + dep.files_to_run.executable.short_path)
# collect the runfiles of the other executables so their own runfiles
# will be available when the top-level executable runs
runfiles = runfiles.merge(dep.default_runfiles)
ctx.actions.write(
output = ctx.outputs.executable,
is_executable = True,
content = "\n".join(executable_paths))
return DefaultInfo(
executable = ctx.outputs.executable,
runfiles = runfiles)
exec_rule2 = rule(
implementation = _impl2,
executable = True,
attrs = {
"deps": attr.label_list(),
},
)
BUILD.bazel
:
load(":defs.bzl", "exec_rule1", "exec_rule2")
exec_rule1(name = "foo")
exec_rule1(name = "bar")
exec_rule2(name = "baz", deps = [":foo", ":bar"])
然后运行它:
$ bazel run //:baz
INFO: Analyzed target //:baz (4 packages loaded, 19 targets configured).
INFO: Found 1 target...
Target //:baz up-to-date:
bazel-bin/baz
INFO: Elapsed time: 0.211s, Critical Path: 0.01s
INFO: 0 processes.
INFO: Build completed successfully, 6 total actions
INFO: Build completed successfully, 6 total actions
foo 123
bar 123