-
Notifications
You must be signed in to change notification settings - Fork 323
Description
Problem and repro
Consider the following:
BUCK
cxx_binary(
name = "bin",
srcs = ["main.cpp"],
modifiers = ["//build/platforms:release"],
)
command_alias(
name = "cmd",
exe = ":bin",
)main.cpp
#include <iostream>
int main()
{
#ifdef NDEBUG
std::cout << "release" << std::endl;
#else
std::cout << "debug" << std::endl;
#endif
return 0;
}> buck2 run :bin
release
> buck2 run :cmd
debug
I would expect :bin to be built as a dependency of :cmd the same way as it is when built directly via the CLI, but it is not.
This is a simplistic example, but basically any modifiers set on targets in the build graph seem to be completely ignored.
I believe this to be a bug, because if a target requires some modifiers to be applied, the build may be completely broken, and buck2 run :cmd will result in a build failure, rather than just the wrong configuration being built.
Some of the things I have tried
Writing a simpler rule
I've written my own command rule, in case there was something weird about command_alias. There is not, I got the same behavior.
Using attrs.arg() or attrs.configured_dep()
Using attrs.arg() and using a string parameter macro to pass :bin (either via $(exe_target) or $(location)) made no difference.
attrs.configured_dep() does not really help, because while it can change the base platform being used, it does not affect modifier application (they get skipped all the same).
Setting the modifier on the CLI
This "works", but is not compatible with my actual use case, where we have modifiers set deep in the build graph, and asking users to also know about them and set them on the CLI is not reasonable.
Using target_compatible_with
Using target_compatible_with instead of (or besides) modifiers is useful to catch missing constraints earlier in the build, but it does not solve the issue: end-users still need to specify all constraints at the top-level target being built, no matter how deep in the build tree those constraints are being used, and how irrelevant they are to the end user.
This is a considerable abstraction leak.
Transistions
Transitions can be used to add constraints to some parts of the build tree.
We could use them for this purpose, but they are significantly more cumbersome to use, less user friendly, and our understanding is that modifiers are supposed to replace them for this use case.