Hello,Our build needs to take the list of requested targets and besides building those we need to run rather complex "binplace" rule on each target which copies given target output files to the required folder structure.This "smells" like a job for validation actions with or without aspect. My first attempts to make validation work are here and they are not successful. Looks like I need some help making validation actions work.
Also I have some related questions:1. Our binplace rule is rather complex and may end up generating multiple actions for each input target. Can I have "validation target" which depends on the artifact generating target OR validation actions must be part of the same target? We don't want to pollute C++ cc_binary (for example) with some highly specialized actions and rather do it externally to the artifact rules.
2. I noticed new flag experimental_use_validation_aspect but cannot find what it's doing or how to use it. Curious.
3. In this mailing list I found older discussion which seems to touch similar problem. Is it still actual?
And one more:
4. When I supply my artifact generating actions with the validation actions - does it mean that no matter which targets are actually requested all validated targets will behave like they are requested? Or what is actually requested still can change it somehow and we can build less than everything which is validated?
Any help?Thank you!Konstantin
--
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/ac6e51c7-0102-4738-8fcd-1ef6f0a11138n%40googlegroups.com.
I got it working, but let me add one more twist to the problem.
Our current binplace rule is instantiated just once and points at its source targets with transition, like this:
binplace_rule = rule(
implementation = _binplace_rule_impl,
attrs = {
"srcs": attr.label(cfg = binplace_transition, providers = [SubsetInfo, TransitiveClosureInfo]),
This transition is one to many and it allows us to build multiple platforms/flavors in one Bazel invocation
Now instead of a single binplace target we are going to have many instances of binplace aspect where each one supposed to binplace one target.
It is all great, but how do we apply transition to aspects?
Aspects don’t get the target to work on as the attribute, instead we just get it as the first parameter of _binplace_aspect_impl(target, ctx):
I don’t understand how to make aspect to follow different flavors of the given targets.
Alex, thank you for the elaborate answer!I have experience with Aspects, but never applied those from the command line.Question: if we request multiple targets and they have some common dependencies - will the Aspect implementation function be invoked only once for each dependency?
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/38c06349-eedf-45d2-b799-cae3d90236bfn%40googlegroups.com.
Aspects in Bazel are mind bending. ☹
I don’t understand why aspects parameters are needed when all aspects have access to all attributes of the rules they traverse through ctx.rule.attr?
From: Alex Humesky <ahum...@google.com>
Sent: Monday, June 5, 2023 3:22 PM
To: Konstantin Erman <kon...@ermank.com>
Cc: bazel-discuss <bazel-...@googlegroups.com>
Subject: Re: [bazel-discuss] Re: Questions about validation actions and aspects
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/DM6PR01MB5644C162DB075B789E98D48BA34FA%40DM6PR01MB5644.prod.exchangelabs.com.
No – no, I don’t need aspect parameters or at least I am not aware of it yet 😊
From that document I learned about aspect parameters and got confused why they are even needed, but that interest at the moment is purely theoretical.
If you have time a short explanation would be nice, but it is very low priority request. Nothing is blocked on it.
Wow, I am glad I asked – it is something very new to me.
Could you add a sample aspect implementation to make it more clear?
The whole idea that the aspect can go “in reverse” to account for the existence of some rules is very novel to me.
Can the parameter be simply “name”?
I consider the following design for binplace, but cannot see it through to the end.
Target B depends on target A. Each target T has a corresponding “T_bin” target which binplaces it. Instead of coding “B depends on A” I am going to code “B depends on A_bin”.
Each binplace target just passes its source targets with all their providers to the DefaultInfo. Also each binplace target defines _validation action which does actual binplacing – copying the sources to the correct place. Those copies in the correct place are bundled to the _validation output group of the binplace target. Example:
cc_library(
name = "A",
# ....
)
binplace(
name = "A_bin",
srcs = ["A"],
)
cc_library(
name = "B",
deps = ["A_bin"],
# ....
)
binplace(
name = "B_bin",
srcs = ["B"],
)
In this example when we request B we get both A and B built and binplaced.
Now the part I struggle with: build has a flag “target_platforms” which could be set for example to “win64, win32, asmjs”. We want one to many transition to build all three target platforms in parallel. I wonder how to wire up this transition to the above design, so that when I do “bazel build B –target_platforms=win64,win32,asmjs” both A and B get built and binplaced for each of the three specified platforms.
One possible solution is for each module (A and B) create “_req” target which would build that module with transition, like this:
requestable_target(
name = "A_req",
srcs = ["A_bin"],
)
requestable_target = rule(
implementation = _impl,
attrs = {
"srcs": attr.label_list(cfg = platforms_transition),
},
)
Binplace location is not per-configuration, it is just one folder structure under the default (root) configuration folder. In the existing design we have single binplace rule (not one per module) which does the transition and therefore knows where the binplace folder is and what configuration specific folders it should pick the binaries from.
With the design above each binplace rule would be invoked for each platform individually and would not know where the central platform independed binplace location is. We need to provide them with this information somehow, i.e. send information from the root of the graph to the dependencies, which is unusual for Bazel.
Also it is ugly to create extra targets “_req” for each module.
How can we design it better?
Konstantin