bazelbuild / rules_rust

Rust rules for Bazel
https://bazelbuild.github.io/rules_rust/
Apache License 2.0
650 stars 409 forks source link

Cannot build a no_std crate that uses a proc macro that uses std #2748

Open ernoc opened 1 month ago

ernoc commented 1 month ago

Given:

rules_rust will pull in the proc macro's dependencies and then propagate the std feature to all crates in the index, meaning no we can no longer build our crate for bare metal.

bmclarnon commented 1 month ago

Here's a repro for the issue (tested with bazel 7.2.1):

Repro steps:

$ touch {anyhow,broken}{.lock,-lock.json} && CARGO_BAZEL_REPIN=1 bazel sync
$ bazel build --platforms=//:x86_64-unknown-none --@rules_rust//:no_std=alloc @anyhow_crate_index//:anyhow @broken_crate_index//:prost-types  # succeeds
$ bazel build --platforms=//:x86_64-unknown-none --@rules_rust//:no_std=alloc @broken_crate_index//:anyhow  # fails
...
error[E0463]: can't find crate for `std`
   --> external/broken_crate_index__anyhow-1.0.86/src/lib.rs:251:1
    |
251 | extern crate std;
    | ^^^^^^^^^^^^^^^^^ can't find crate
    |
    = note: the `x86_64-unknown-none` target may not support the standard library

prost-types depends on prost-derive, which is a proc macro (i.e. provides compile-time codegen rules). prost-derive depends on anyhow with the std feature -- which is okay because the usage only happens at compile time. But crates_repository merges features across all dependencies -- including those reached via proc macros -- resulting in the std feature being added to @broken_crate_index//:anyhow (compare the anyhow entries in anyhow-lock.json and broken-lock.json).

This is similar to https://github.com/bazelbuild/rules_rust/issues/205, but in addition to building proc macros for the host platform, I believe dependencies of proc macros (or at least their features) also need to be isolated between the host and target platforms.