I write the below bazel rule for incremental test.
This rule(foo_library
) has a dependency property.
When there are no dependencies, it creates a file with its own name, filling the contents of the file with its own name.
When there is a dependency, it creates a file with its own name, and at this time, the contents of the file are filled by adding its own name to the contents of the file created by the dependency target.
In this test, foo3
, foo2
, and foo1
are linked as dependencies, so I expected 3 files to be created, but only foo3
was created.
What could be the problem? Hera are my test bazel code, build command and log message.
# ~/rules/dev.bzl
def _foo_binary_impl(ctx):
this_name = ctx.attr.name
file_name = ctx.actions.declare_file(ctx.label.name)
print("##-000 this_name: {}".format(this_name))
print("##-001 file_name: {}".format(file_name))
file_content = ""
if ctx.attr.deps:
for dep in ctx.attr.deps:
t1 = dep[DefaultInfo].files.to_list()[0].basename
t1 = t1 + this_name
print("##-100 t1: {}".format(t1))
file_content = t1
else:
t2 = this_name
print("##-101 t2: {}".format(t2))
file_content = t2
ctx.actions.write(
output = file_name,
content = file_content,
)
return [
DefaultInfo(
files = depset([file_name])
),
]
foo_binary = rule(
implementation = _foo_binary_impl,
attrs = {
"deps": attr.label_list(),
},
)
# build command and log
$> bazel build -s //rules/example:foo3 1 х 11:38:08
DEBUG: ~/rules/dev.bzl:10:10: ##-000 this_name: foo1
DEBUG: ~/rules/dev.bzl:11:10: ##-001 file_name: <generated file rules/example/foo1>
DEBUG: ~/rules/dev.bzl:25:14: ##-101 t2: foo1
DEBUG: ~/rules/dev.bzl:10:10: ##-000 this_name: foo2
DEBUG: ~/rules/dev.bzl:11:10: ##-001 file_name: <generated file rules/example/foo2>
DEBUG: ~/rules/dev.bzl:19:18: ##-100 t1: foo1foo2
DEBUG: ~/rules/dev.bzl:10:10: ##-000 this_name: foo3
DEBUG: ~/rules/dev.bzl:11:10: ##-001 file_name: <generated file rules/example/foo3>
DEBUG: ~/rules/dev.bzl:19:18: ##-100 t1: foo2foo3
INFO: Analyzed target //rules/example:foo3 (3 packages loaded, 8 targets configured).
INFO: Found 1 target...
Target //rules/example:foo3 up-to-date:
bazel-bin/rules/example/foo3
INFO: Elapsed time: 0.107s, Critical Path: 0.00s
INFO: 2 processes: 2 internal.
INFO: Build completed successfully, 2 total actions
Build foo3
and expected 3 files(foo1
, foo2
, foo3
) are generated. howver, foo3
is generated only.
If
ctx.attr.deps
is nonempty,foo_binary_impl
writes a file with content that depends on the file name of the last file inctx.attr.deps
rather than the content of the last file inctx.attr.deps
. No dependency on any file inctx.attr
is ever introduced. Therefore, Bazel does not build anything indeps
when producing the output offoo_binary_impl
.To make the output of
foo_binary_impl
depend on the content of dependencies, make an action to produce the final output that takes the dependency files as inputs. For example, to concatenate all the files indeps
into the output: