-
Notifications
You must be signed in to change notification settings - Fork 0
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
Create compatibility.bzl #1
base: master
Are you sure you want to change the base?
Conversation
The "verbose" operators all use a named incompatible target, which means you get error messages like this:
The named constraint is meaningless, and just a placeholder. Alternatively, we can rely on the
Here, |
I hate myself for even suggesting this... but using some clever unicode... We can yield this instead:
|
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.
Very cool! Would you happen to have an accompanying test file that you're testing these out in? Would be fun to play with this a bit. Obviously it's easy to set something up manually to play with this, but I was just curious.
lib/compatibility.bzl
Outdated
|
||
def _any_of(settings): | ||
no_match_error = "Didn't match any conditions." # TODO(trybka): concat setting names? | ||
return selects.with_or({tuple(settings): [],}, no_match_error = no_match_error) |
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.
Avoiding no_match_error
would be good I think. Otherwise you get analysis errors instead of target skipping.
I.e. this should probably be "//conditions:default": [INCOMPATIBLE_TARGET]
, no?
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.
d'oh -- good point. I was mostly down the rabbit hole testing on a single broken target.
yeah, this is a non-starter for skipping.
lib/compatibility.bzl
Outdated
settings_name = "_and_".join([s.split(":")[1] for s in settings]) | ||
name = settings_name.replace(":", "-").replace("//", "").replace("/", "_") | ||
if not native.existing_rule(name): | ||
selects.config_setting_group(name = name, match_all = settings) |
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, this makes sense. I never tried to implement all_of
before, but it makes sense that you can't do it with a single select()
statement.
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.
It's cool to see composition of Starlark libs actually working. I always worry the "non-native" part of selects
means using config_setting_group
as a library call could blow up in unexpected ways. Happy to see it all remains smooth.
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 think the only sharp/weird edge here is the fact that this has to be a named rule (which necessitated the existing_rule
check). If you have alternatives for how to make unique or unnamed targets here, that would improve things, I think.
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.
So... I had a thought. Would a simple implementation of all_of
look like this?
def _all_of(settings):
return settings
The target_compatible_with
attribute already implements AND logic by default.
Maybe as per your comment below, maybe don't provide all_of
at all? I like it there for consistency, but maybe it's superfluous?
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 would only work if settings
contained only constraint_values
. In the case I want to support, raw config_settings
don't work here. (Apparently anything that provides ConstraintValueInfo
would work, but currently nothing else does, and that provider is behind some flag anyhow.)
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.
Ah dang. Yeah, I keep forgetting about that, apologies!
lib/compatibility.bzl
Outdated
name = settings_name.replace(":", "-").replace("//", "").replace("/", "_") | ||
if not native.existing_rule(name): | ||
selects.config_setting_group(name = name, match_all = settings) | ||
compat_name = "compatible_with_all_of_" + name |
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.
Neat idea!
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.
What's the difference between this new value and just @platforms//:incompatible
?
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.
@platforms//:incompatible
cannot appear twice in this attribute--so if two selects resolve to incompatible, there will be an error.
I'll try to add a test here. |
|
||
All of the settings must be true to get an empty list. Failure to match will result | ||
in an incompatible constraint_value for the purpose of target skipping. | ||
|
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 you expand this to talk about constraint_value
targets not working with all_of
because of bazelbuild/bazel#13047?
As a work around, folks should use something like this if they need to mix constraint_value
and config_setting
targets:
target_compatible_with = [":constraint1", "constraint2"] + compatbility.all_of([":config1", ":config2"]),
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 commented on the bug but I'm really hoping that bug is fixable without a major effort. It's ultimately a silly circular dependency problem. Those are always awkward, but conceptually not too hard to think about ways of short circuiting.
No description provided.