facebook / buck2

Build system, successor to Buck
https://buck2.build/
Apache License 2.0
3.33k stars 194 forks source link

`configured_alias` and configuration modifiers #603

Open toothbrush7777777 opened 2 months ago

toothbrush7777777 commented 2 months ago

I have a question about the interaction between configuration modifiers and configured_alias. At present, you can use configured_alias to build a target for a specific platform, irrespective of the current target platform. Ideally, the API should be changed to fit with the upcoming configuration modifiers (e.g. passing a list of configurations instead of a target platform). Therefore, configured_alias targets should be treated as if they are top-level targets.

Maybe the new configuration modifiers API would be able to reduce the need for configured_alias. However, there may also be a need to specify exactly which configuration modifiers apply – or in other words, to not inherit any configuration modifiers from PACKAGE or elsewhere – when building certain targets.

For example, let's say you want to create an Apple fat binary. You would need to build the target application for two different configurations and then invoke a host tool to combine them into one fat binary. This can currently be represented with a (macro) rule by creating configured_alias rules for macos-x86_64 and macos-arm64, with a genrule for linking them with lipo:

cxx_binary(
    name = "app",
    srcs = ["main.cpp"],
    link_style = "static",
)

configured_alias(
    name = "app-x86_64",
    actual = ":app",
    platform = "@platforms//:macos-x86_64",
)

configured_alias(
    name = "app-arm64",
    actual = ":app",
    platform = "@platforms//:macos-arm64",
)

genrule(
    name = "app-universal",
    bash = 'lipo -create -output "$OUT/app" "$(location :app-x86_64)" "$(location :app-arm64)"',
    outs = {
        "output": ["app"],
    },
    default_outs = ["app"],
    visibility = ["PUBLIC"],
)

This can then be built using buck2 build :app-universal.

Are there any plans for updating or replacing configured_alias?

scottcao commented 2 months ago

For the fat binary use case, we support this internally with apple_universal_executable rule using a split transition. The transition can apply changes on top of the existing configuration to get the behavior you want without defining a configured_alias target for every split you want to create.

The way transitions and modifiers are applied today don't interact in the best of ways. For example, an incoming edge transition can override any modifier from the command line, which is probably not ideal. I'm currently looking at unifying how transitions and modifiers work into one coherent system.

On configuration_alias, we haven't discussed this internally, but I would agree with you that we should aim to replace configured_alias with a transition/modifier-based replacement. One of the main reasons we have configured_alias support in buck2 is because buck1 supported configured_alias and not transitions.

toothbrush7777777 commented 1 month ago

Yeah, that sounds reasonable. I'd like some way to specify an exact list of configuration modifiers for an aliased target which does not inherit from anywhere, though. The Apple universal binary rule was just an example; in reality, we need to build specific release targets with specific config modifiers (e.g. one might require x86-64 + avx2 + speed optimisations + debug info, another AArch64 v9.3 + NEON (or SVE) + size optimisations + no frame pointers, and yet another x86-64-v3 (avx2 + bmi) + speed optimisations + frame pointers). I understand that Meta currently uses mode files for this use case, but since config modifiers are supposed to be replacing them, having a well-supported alternative would be best.