bazel-compile-commands-extractor icon indicating copy to clipboard operation
bazel-compile-commands-extractor copied to clipboard

Wrong bazel-out path when target uses transition to modify features

Open kon72 opened this issue 1 year ago • 4 comments

In the reproducible code below, bazel build //:b would run the compilation under the directory bazel-out/darwin_arm64-fastbuild-ST-299abaa87f6b, but the generated compile commands have bazel-out/darwin_arm64-fastbuild-ST-3b9a2f2abd71 in place of that.

After some digging, it looks --features flags used in the aquery command is causing the bazel-out hash to change.

As a quick workaround, omitting features flag from aquery args fixed this issue. (But surely it's going to surface up some other problems...)

Minimal reproducible example

transition.bzl
def _test_transition_impl(settings, attr):
    _ignore = [attr]

    features = settings["//command_line_option:features"] + ["foo"]

    return {
        "//command_line_option:features": features,
    }

_test_transition = transition(
    implementation = _test_transition_impl,
    inputs = ["//command_line_option:features"],
    outputs = ["//command_line_option:features"],
)

def _test_rule_impl(ctx):
    return [DefaultInfo(files = depset(ctx.files.cc_target))]

test_rule = rule(
    implementation = _test_rule_impl,
    attrs = {
        "cc_target": attr.label(cfg = _test_transition, mandatory = True),
        "_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
    },
)
BUILD
load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands")
load("//:transition.bzl", "test_rule")

refresh_compile_commands(
    name = "refresh_compile_commands",
    targets = {
        ":b": "",
    },
)

cc_binary(
    name = "a",
    srcs = ["a.cc"],
)

test_rule(
    name = "b",
    cc_target = ":a",
)
スクリーンショット 2024-01-09 16 48 49

kon72 avatar Jan 09 '24 08:01 kon72

It's ugly, but a solution I can come up with is:

  1. Run aquery with --features flags to query compile commands (that contain wrong bazel-out path)
  2. Run aquery again but this time without --features flags, to get a correct bazel-out path
  3. Replace wrong paths in commands with correct ones

kon72 avatar Jan 09 '24 23:01 kon72

Thanks so much for tracking it down and reporting, Kon.

We really do need those features off (for the reasons in the comments next to them), and compiler param files need to be on for the actual compilation on Windows. I can't think of a better solution offhand than the one you propose.

Might also be worth filing a Bazel issue?

cpsauer avatar Jan 10 '24 06:01 cpsauer

Hmm, actually, I'm seeing this work okay for Android builds in my personal project. I'm wondering if, perhaps, they turned on param files by default in the Mac toolchain you're using, and that's why we're seeing it? I still can't think of a better solution, unfortunately.

cpsauer avatar Jan 10 '24 06:01 cpsauer

I did a more thorough test on my main project and removing the --feature=-'s in refresh.template.py didn't seem to lead to changes in the bazel-out paths there, for the macOS host as well as for transitions to iOS and Android. So it must be something about that transition type? Super duper weird.

cpsauer avatar Jan 20 '24 06:01 cpsauer