-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support constraint_value directly in select() #12071
Conversation
No more need for a redundant config_setting. See bazelbuild#8583 for an example. This was a bit subtle. constraint_value can't directly export a ConfigMatchingProvider because it needs to know the platform to determine if it's a match. But platforms are built out of constraint_values, so the platform isn't available yet. So the parent target with the select() provides this detail. Also beautifies "invalid select() key" errors in support of bazelbuild#11984. Fixes bazelbuild#8583. RELNOTES[NEW]: select() directly supports constraint_value (no need for an intermediate config_setting). PiperOrigin-RevId: 327885099 Change-Id: Ifbdfa275ff83f0cb30207a5bd77aca317599fc21
@philsc @AustinSchuh FYI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really clever and I like it.
Most of my comments are not actionable, just ways I want to think about the API. I will probably come back tomorrow and turn some of them into standalone issues, sorry for adding my stream-of-consciousness to your PR review.
``` | ||
|
||
This saves the need for boilerplate `config_setting`s when you only need to | ||
check against single values. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we give an example of using config_setting for multiple constraint values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example before here already does this, so I think we have good coverage overall: https://docs.bazel.build/versions/3.5.0/configurable-attributes.html#platforms.
* Returns a {@link ConfigMatchingProvider} that matches if the owning target's platform includes | ||
* this constraint. | ||
* | ||
* <p>The {@link com.google.devtools.build.lib.rules.platform.ConstraintValue;ConstraintValue} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The @link
syntax looks wrong here, what are you intending to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Just removing the part after the semi-colon works. I fully qualified it because otherwise an import on its package adds a dependency which messes with the BUILD dependency structure. Which isn't worth it just for a code link (I believe that's our actual style guidance too: to not add new dependencies just for doc links).
* | ||
* <p>Instead, a target with a <code>select()</code> on a {@link | ||
* com.google.devtools.build.lib.rules.platform.ConstraintValue} passes its platform info to this | ||
* method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is really clever. :)
env, | ||
ctgValue, | ||
transitivePackagesForPackageRootResolution, | ||
unloadedToolchainContexts == null | ||
? null | ||
: unloadedToolchainContexts.getDefaultToolchainContext().targetPlatform(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All toolchain contexts for the same configured target, regardless of exec group, should have the same target platform (right @juliexxia ?)
We should consider enshrining that in the API by adding a unloadedToolchainContexts.targetPlatform() method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that sounds right and looks right according to https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java;l=531?q=ConfiguredTargetFunction&ss=bazel
@katre I like that idea. Do you think there's anything else to discuss there? If not I can mail something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, it makes sense. Go ahead if you have time, I was going to file an issue and then deal with it later :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear, this suggestion is for a followup PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, nothing to do in this PR.
// If platformInfo == null, that means the owning target doesn't invoke toolchain | ||
// resolution, in which case depending on a constraint_value is non-sensical. | ||
configConditions.put( | ||
entry.getLabel(), constraintValueInfo.configMatchingProvider(platformInfo)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add a ConfigMatchingProvider.configMatchingProvider(???) method, so that we'd only have one branch here? We'd have to do some weird generic tricks to get the type right, and it might not be worth it, but if we ever add a third, we should consider a way to collapse the choices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Given the frequency of rule expansion (very infrequent), I vote for not supporting that much extra abstraction yet. But I added a note with your suggestion if this ever goes further.
I assure you my first pass on this looked 10,000 times worse! I was surprised and happy to reduce this to something so non-invasive.
No worries, thanks for the comments. I'll follow up properly on them as soon as I can. |
Is this supposed to work in a filegroup?
but the corresponding version with a config_setting works correctly, as does the select clause in (for example) a sh_binary. cc @UebelAndre |
Interesting catch! My first instinct was to say it shouldn't matter what rule uses the |
One other thing I noticed is the ctx.attr.bool does not accept select statements. Not sure if that's directly related to this 😅 |
Found the problem! bazel/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java Line 814 in 63e0392
In this example Matching the I think the idea is that i believe
|
Filegroup was explicitly added to the set of rules that don't participate in toolchain resolution (and that thus don't have a target platform) back during the early development. As I recall, it led to a cycle in evaluation, because filegroups were needed at a low-enough level that we couldn't process loading platforms without them. I'll take another look at this and see if we can turn it back on. |
If that doesn't make sense conceptually, I think we could conditionally load the platform when we notice a |
No more need for a redundant config_setting. See #8583 for an example.
This was a bit subtle. constraint_value can't directly export a ConfigMatchingProvider because it needs to know the
platform to determine if it's a match. But platforms are built out of constraint_values, so the platform isn't available
yet. So the parent target with the select() provides this detail.
Also beautifies "invalid select() key" errors in support of #11984.
Fixes #8583.
RELNOTES[NEW]: select() directly supports constraint_value (no need for an intermediate config_setting).