Hello,
I struggle to express particular build behavior and seek for
some leads how it can be done with Bazel.
Our build produces many binaries which can be requested in any combinations. Some of those binaries require post processing, for which we have a custom rule.
First problem: how to make sure that particular targets get post-processed when they are requested or are a dependency of something requested?
Next level of complexity: binaries are statically assigned
to the groups and post-processing must handle all binaries in a group in one
shot.
Example of the problem: A and B could be assigned to a group. When either of them (or both) are requested or either of them is a dependency of the target requested we need to post-process them both together even if only one was requested.
We can implement a rule such as “postprocess_group_AB” which
would depends on both A and B, but how to get it executed when only A (for
instance) is requested?
Any ideas?
Thank you!
Konstantin
defs.bzl
:def _post_process_impl(ctx): total_lines = ctx.actions.declare_file("total_lines") ctx.actions.run_shell( inputs = ctx.files.srcs, outputs = [total_lines], command = "cat %s | wc -l > %s" % (" ".join([s.path for s in ctx.files.srcs]), total_lines.path), ) for src, output in zip(ctx.files.srcs, ctx.outputs.outs): ctx.actions.run_shell( inputs = [src, total_lines], outputs = [output], # processing depends on the content of all inputs command = "cp {src} {out} && cat {total_lines} >> {out}".format( src = src.path, out = output.path, total_lines = total_lines.path) ) return [DefaultInfo(files = depset(ctx.outputs.outs))] _post_process = rule( implementation = _post_process_impl, attrs = { "srcs": attr.label_list(allow_files = True), "outs": attr.output_list(), }, ) def post_process(name, srcs): outs = ["%s_processed" % src for src in srcs] # order matters here for zip() above _post_process( name = name, srcs = srcs, outs = outs, )
BUILD
:load(":defs.bzl", "post_process") post_process( name = "post", srcs = ["file1", "file2"], ) genrule( name = "pkg1", srcs = [":file1_processed"], outs = ["pkg1.zip"], tools = ["@bazel_tools//tools/zip:zipper"], cmd = "$(location @bazel_tools//tools/zip:zipper) c $@ $<", ) genrule( name = "pkg2", srcs = [":file2_processed"], outs = ["pkg2.zip"], tools = ["@bazel_tools//tools/zip:zipper"], cmd = "$(location @bazel_tools//tools/zip:zipper) c $@ $<", )
file1
:line 1 line 2
file2
:line a line b line c
--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/f7ae4156-b1d2-4c52-8274-6799ac3957a1n%40googlegroups.com.
Trivial example of the target post-processing would be copying of the produced binaries to designated output folder, for example:
bazel build t1 t2 t3
should achieve not only building of the targets t1, t2 and t3 and their dependencies, but also invoke post-processing (in some form) to copy the binaries of t1, t2 and t3 to designated folder and also all dependencies must do the same.
The best I can think of would be using the aspect from the command line, i.e.
bazel build t1 t2 t3 --aspects postproc.bzl%postproc_aspect
And let the aspect to post-process all given targets and their dependencies.
This may work (I have not implemented PoC yet), but unfortunately it falls apart when Part 2 kicks in – for some targets post-processing is more complex and for some targets interconnected, for example:
Requirement: targets t1 and t2 must be always post-processed in one shot – together.
If neither target is requested then no post-processing is necessary.
If either (or both) targets are requested or if one (or both) of them is a dependency of something requested, then we need to invoke post-processing action on both t1 and t2 even if only one is needed.
-- by "statically assigned to groups", do you mean "the groupings are encoded in the build files"?
Yes, it is known upfront and never changes.
-- And does post processing depend on the content of bin_a and bin_b
Yes. It
calculates combined hash of all binaries in one post-proc group.
Konstantin