Per Westling
Per Westling

Reputation: 23

Can I get bazel to trigger extra actions after a target is built?

I have a bazel rule that produces an artifact. How should I do to add a post-processing step with the artifact produced as a dependency?

We have a big build system where our macros are used in several BUILD files. So now I need to add another step that would use the artifacts produced by a specific macro to create another artifact, and hopefully without having to update all BUILD files.

In a non-bazel context I would probably use something that triggers the extra step, but in the bazel context, the best thing I have come up with have been to add a new macro, that uses the rule created by the other macro as a dependency.

It is something like this today:
Macro M1 generate rule R1 - which produce artifact A.
Buildfile B use macro M1 and when that target is built artifact A is produced.

So I can now add a macro M2 that generate rule R2, which produce artifact B.
Artifact A is a dependency to this rule.
The users will use macro M2 instead.

But can I do this in some other way?

Example of a use case could be that I have a macro that produces a binary, and I now want to add e.g. signing. "The users" will still want to build that binary, and the signed artifact is created as a bi-product of little interest for the users.

Upvotes: 0

Views: 939

Answers (1)

László
László

Reputation: 4271

You could update M1 to call M2.

M1 calling M2 merely declares rules. Typically macros look like this:

def M1(name, arg1, ...):
    R1(name=name, arg1=arg1, ...)

When you build M1 rule "//foo:bar", you actually build R1 named "//foo:bar". So you must update M1 to call R1 using some other name than name, e.g. name + "dep", and call M2 with the name and pass R1's name as a dependency. So then if you build "//foo:bar", you'll build M2's underlying rule (R2), which depends on R1, and so Bazel first builds R1 (and produces A), and then R2 (consuming A)..

One more thing: Bazel preprocesses macros into actual rules, before it loads the rules in the BUILD file. You can inspect the result of this preprocessing, to see what rules you actually have in the package, like so:

bazel query --output=build //foo:*

Upvotes: 1

Related Questions