Skip to content

Add a build setting to announce crate scope #3408

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

Closed
wants to merge 3 commits into from

Conversation

yuzhy8701
Copy link
Contributor

@yuzhy8701 yuzhy8701 commented Apr 14, 2025

This build setting is not used internally, but provides a way for (transitive) dependencies to be aware that they are being compiled for a rust crate.

A transition is added to all rust rules, which sets the build setting to one of either: regular or proc_macro. A third value none is provided as a default for targets outside of the (transitive) scope of any rust crates. The change also adds 3 config_settings, one for each value of the build setting, to provide conditions others can select() on.

Examples of complex scenarios enabled by this change:

  1. Build with a mac-x86_64 toolchain on mac-aarch64 platforms (with Rosetta) - everything (including host tools) is compiled for aarch64 while proc_macros must be compiled for x86_64.
  2. A cc_library linked to both a cc_binary and a rust_binary (directly or transitively), but needs slightly different build flags when used for rust crates.
  3. Use separate cc toolchains for C++ and Rust targets in the same build
    • Highly customized cc_toolchain that doesn't work for linking rust crates
    • Use a mingw toolchain with the windows-gnu flavor of rust toolchain, while building the rest C++ targets with MSVC toolchain.

@yuzhy8701 yuzhy8701 force-pushed the toolchain-platform branch 2 times, most recently from a5b8a83 to a2e2695 Compare April 14, 2025 21:35
This build setting is not used internally, but provides a way for
dependencies to be aware that they are being compiled for a rust crate.

Examples of complex scenarios allowed by this change:

1. Build with a mac-x86_64 toolchain on mac-aarch64 platforms (rosetta)
   - everything (including host tools) is compiled for aarch64 while
   proc_macros must be compiled for x86_64.
2. A `cc_library` linked to both a `cc_binary` and a `rust_binary`, but
   needs slightly different build flags when used for rust crates.
@yuzhy8701 yuzhy8701 force-pushed the toolchain-platform branch 3 times, most recently from c90ed00 to 8114917 Compare May 21, 2025 08:30
yuzhy8701 added 2 commits May 21, 2025 01:47
The change of bin_dir caused some tests to fail. Now they use a more
robust version, havested with an aspect inspecting on the
target-under-test.
rustdoc_test fails when its crate dependency and its toolchain
dependency are from different configurations, because the stripped roots
did not include any toolchain files.

This change simplifies the logic by collecting roots from all the
inputs.
@yuzhy8701 yuzhy8701 force-pushed the toolchain-platform branch from 8114917 to 5229b37 Compare May 21, 2025 08:47
@scentini scentini self-requested a review May 21, 2025 09:23
@scentini
Copy link
Collaborator

Could you speak more on this one:

Build with a mac-x86_64 toolchain on mac-aarch64 platforms (with Rosetta) - everything (including host tools) is compiled for aarch64 while proc_macros must be compiled for x86_64.

I'd expect this to work today, given that there is a transition to exec config for proc macros, the toolchain for exec config could be x86_64 while the target config could stay aarch64.

@yuzhy8701
Copy link
Contributor Author

yuzhy8701 commented May 21, 2025

@scentini Sure! This is what happens in our build:

  • Our build machines (host platforms) are a mix of mac-x64 and mac-aarch64
  • We use a custom build of rust toolchain where:
    1. The tools (rustc, rustdoc, etc) are pre-built for mac-x64 so they can run on all the builders (native or via Rosetta).
    2. The rust standard libs are built for mac-aarch64, which is also our target platform.
  • The builds are mixed-language (Rust and C++).

Everything works just fine on the x64 builders. But on aarch64 builders proc macros fail to load because they are built for aarch64 while the compiler expects a x64 binary.

We tried a few workarounds:

  1. Set --host_platform to mac-x64 for the entire build.
    • This worked, but build performance got a hard hit. Some of our tools we build from source runs rather slow with Rosetta.
  2. Transit --host_platform to mac-x64 for all the rust targets (using wrapper rules with a transition)
    • Worked initially, until we are pulling in a 3rd-party crate that we don't control the BUILD file.
  3. Transit --platforms to mac-x64 for only the proc macro targets (using a wrapper rule with a transition)
    • This is our current workaround, but will face the same 3rd-party issue soon.

In an ideal world, we can add a toolchain attribute to inform the "native" platform of the rust tools, then transit to that platform when building proc macros (fallback to the exec transition). But it is not a supported use case of Bazel, since transitions cannot access toolchains or get providers from attributes; nor can a starlark transition fallback to the exec transition.

@yuzhy8701
Copy link
Contributor Author

yuzhy8701 commented May 22, 2025

Hmm.... I can't seem to fix the aspects (Clippy, etc). Those aspects run in a different configuration than the target they are applied to, so they get a different output directory and stuff like sibling=target.output.file break. There doesn't seem to be a way in Bazel to force aspects to run with the same configuration as their underlying target.

I'll seek other ways to resolve our problem. @scentini thanks for your time!

@yuzhy8701 yuzhy8701 closed this May 22, 2025
@yuzhy8701 yuzhy8701 deleted the toolchain-platform branch May 22, 2025 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants