-
Notifications
You must be signed in to change notification settings - Fork 204
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
Can configs and constraints be restricted to targets selectively? #385
Comments
you can express OR in target_compatible_with. It's something like this:
|
Ok, that solves the immediate problem, but for educational purposes is there any way to say that I want a target B which depends on target A, and B gets some target-specific constraints added to its configuration that A doesn't know about? Intuitively, it seems like distinct targets have different needs, so you would need a way to have domain specific constraints attached to targets but not their dependents or ancestors. |
I wonder if this could be solved by having the transition impl function be allowed to return either a single PlatformInfo, or a 2-tuple of PlatformInfos. If it returns a single PlatformInfo, it behaves as it does today. If it returns a 2-tuple, then first item in the tuple is the configuration to be used for instantiating the specified target, and the second item in the tuple is the configuration to be used for instantiating dependent targets. Unless there's already a way and I'm missing something. |
To expand a bit on what @zjturner is saying, I think this quickly ends up as the configuration trimming problem that we discussed a fair bit at the very start of the Buck2 project. Imagine you have a messaging library that depends on a core library. Imagine the messaging library has 3 different settings (m1, m2, m3), and the core library has 3 different settings (c1, c2, c3). You could imagine:
How did we end up doing the Java/native split without duplicating all Java libraries on two platforms? We had the idea that you might observe what configuration was actually used, and then somehow trim the configuration to just the used subset, and then add sharing. The ideas were fairly complex, and even though I think I believed them at the time, within a month or two of our initial discussions I couldn't understand them. |
Maybe it's impossible due to the design, but why can't there just be constraints passed directly into the instantiation of the rule?
Transition rules are a bit of a pain to use, but if the above doesn't work, then you could imagine the same thing with the transition rule solution. All I really need is a way to make the transitioned constraints not be transitively inherited by the downstream targets. The documentation describes a transition rule as "applying a function to the configuration and using the output for the target and all dependent targets". All that has to happen is for there to be a way to opt into semantics of "apply a function to the configuration and using the output for the target, but not any dependent targets". |
For exported constraints, that certainly should be handled by transitions, and if it's difficult to use transitions in that way it just points to improvements needed in the transitions api rather than an entirely new category of behavior on targets. But using it for that is particularly risky. If "foo" there depends on "bar" and "baz" also depends on "bar" but not via a dep on "foo", they'd actually get different instances of "bar" because "baz" wouldn't have the constraints that foo added. In the way you specified it here, it sounds like it'd apply to all deps including random tools used for generated code (say, appearing in srcs) and for toolchain deps. I would pretty much discourage trying to go that route at all though, I think I'd need to see a pretty fleshed out use case to be convinced that it doesn't actually have a bunch of bad behavior that would make it not work at all in practice. Adding exported_constraints to all deps in a particular attribute (or set of attributes) has less risk, but will probably still be a challenge in practice. The self constraints thing is more interesting. I could certainly see it being useful to have sort of target-local or package-local constraints. I think there should be some consideration if the usecase for that would be better served by extending the package values api (i.e. should we add select over package values? add target-level equivalent of package values?) or by extending the (already quite complex) configurations apis. |
I actually don't understand the package system at all, so I guess that's something for me to investigate. I also realized shortly after posting that putting the constraints directly on the target instantiation probably wouldn't work, because the whole point of a constraint is to be able to Ultimately self-target-only constraints is the use case though, so I'd be happy with anything that moves closer to that. |
The I'm starting to wonder if just using |
How does buckconfig interact with a remote cache? my understanding is that the target configuration hash doesn’t change when you use buckconfig, so your remote cache is going to end up with whatever version was specified in the user’s buckconfig who built it last. Maybe it’s not a problem in practice, but at that point it seems like it’s effectively a constant, so why even have a buckconfig setting for it? |
The remote cache isn't poisoned by buckconfig. The buckconfig doesn't change the output path, but if you change the The remote cache is indexed by digest, which is the full command line and the hash of all inputs. The target configuration hash changes the output path, and the output path always ends up in the command line somewhere (otherwise you wouldn't know where to put the output), so target configuration changing does mean the digest changes. But that's more a side effect than how we track it. |
Ok, so IIUC if Alice builds If I understood correctly, then what do you mean exactly by having "part" of the messaging library built differently? Are you referring to a situation like this?
So in this case, two different users can share the artifact for |
The target configuration hash isn't part of the cache key, only the command line and input files are. But, the target configuration hash always shows up in the command line as As to your example, if you have different configuration that the select works on, the the output path of If you change to a
Now you will share
But those downsides don't seem a massive problem for you. Internally we use |
We have an audio processing library internally, and this audio library only supports windows and mac. If building on Linux, the audio library should not be present. We'd like to represent this with a
target_compatible_with
, but the semantics of that are an AND, not an OR (in other words, we can't saytarget_compatible_with = linux | windows
.At the same time, I don't know how to selectively attach a set of constraint_values, or config_settings, to a target. I can stick them on the platform object when creating the top-level
ExecutionPlatformInfo
, but this is global to all targets.A transition rule seems like it will work, however the documentation states that when dependencies are resolved, they are resolved with the transformed configuration. This would suggest that if I have A and B where B depends on A, and I apply the transition rule to B, then A will be built with the transformed configuration. This isn't what I want though, I want only B to have the transformed configuration because otherwise A will have configuration info that isn't relevant and is polluting the configuration hash.
Is this possible?
The text was updated successfully, but these errors were encountered: