rules_rust icon indicating copy to clipboard operation
rules_rust copied to clipboard

gen_rust_project seems to be confused by different compilation modes.

Open adamfaulkner-at opened this issue 1 year ago • 1 comments

Hello! I'm having an issue where this command does not generate a correct rust-project.json for my project. Specifically, it excludes some crates:

RUST_LOG=trace bazel run @rules_rust//tools/rust_analyzer:gen_rust_project

I see a line like this for each of the excluded crates:

[2024-07-02T19:03:23Z WARN  gen_rust_project_lib::aquery] Skipping missing crate_spec file: "/private/var/tmp/_bazel_adam.faulkner/065dfc4b5a8c72f61fb4b946404058a5/execroot/_main/bazel-out/darwin_arm64-opt/bin/server_shared/rust/collections/collections.rust_analyzer_crate_spec.json"

I noticed that these crate_spec.json files actually are generated for darwin_arm64-fastbuild, so I tried to build these using this command:

bazel build -c opt --norun_validations --aspects=@rules_rust//rust:defs.bzl%rust_analyzer_aspect --output_groups=rust_analyzer_crate_spec,rust_generated_srcs //...

After this, the gen_rust_project command started working. I've found a few other workarounds as well, including defining "dummy" test targets in these projects that are excluded.

I tried to read the code and understand what is going on, but I was not able to really understand what is going on here. It seems like there's probably some code that assumes an optimized build was created, but the build command does not run in this mode.

adamfaulkner-at avatar Jul 02 '24 19:07 adamfaulkner-at

We are wrapping our libraries in the following transition to force them to build optimized.

def _change_compilation_mode_to_opt_impl(_settings, _attr):
    return {"//command_line_option:compilation_mode": "opt"}

change_compilation_mode_to_opt = transition(
    implementation = _change_compilation_mode_to_opt_impl,
    inputs = [],
    outputs = ["//command_line_option:compilation_mode"],
)

def _build_opt_impl(ctx):
    actual = ctx.attr.actual[0]
    return [
        actual[CcInfo],
        actual[DefaultInfo],
    ]

build_opt = rule(
    implementation = _build_opt_impl,
    provides = [CcInfo],
    attrs = {
        "actual": attr.label(cfg = change_compilation_mode_to_opt),
        "_allowlist_function_transition": attr.label(
            default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
        ),
    },
)

And then in the BUILD file, we tag the underlying library as manual and transition it:

rust_shared_library(
        name = name,
        # V8 symbols come from the binary loading us.
        rustc_flags = ["-C", "link-args=-undefined dynamic_lookup"],
        tags = ["manual"],
        **kwargs
    )

    build_opt(
        name = name + "_opt",
        actual = name,
    )

Any suggestions how to have gen_rust_project figure out what's going on?

DavidZbarsky-at avatar Jul 02 '24 20:07 DavidZbarsky-at