Description
crate_universe resolves Cargo features once across the whole workspace and emits a single shared target per crate, used by every target triple. So a feature enabled by any workspace member is enabled for that crate on all triples, and there is no way to drop a feature (or the dependencies it brings in) for a specific triple. Cargo itself resolves features per target and wouldn't do this; crate_universe collapses that distinction.
This breaks cross-platform workspaces where a feature is fine on one triple but not another. Concretely: one member (built for a host triple) enables the net feature in Tokio. The shared tokio target then has net on for wasm32-unknown-unknown too, pulling in mio and socket2. They don't build there — even though the Wasm member only uses rt/macros/time from Tokio. The Wasm build fails with
Only features sync,macros,io-util,rt,time are supported on wasm.
Reproduction steps
Two Rust crates that depend on Tokio with different Cargo features. First crate:
[package]
name = "native-app"
version = "0.0.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["net"] }
Second crate:
[package]
name = "wasm-app"
version = "0.0.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["rt", "macros", "time"] }
Bazel workspace setup:
crate.from_cargo(
name = "crate_index",
cargo_lockfile = "//:Cargo.lock",
manifests = ["//:Cargo.toml", "//native-app:Cargo.toml", "//wasm-app:Cargo.toml"],
supported_platform_triples = [
"x86_64-unknown-linux-gnu",
"wasm32-unknown-unknown",
],
)
Build file:
rust_library(
name = "wasm-app",
srcs = glob(["src/**/*.rs"]),
edition = "2021",
target_compatible_with = ["@platforms//cpu:wasm32"],
deps = all_crate_deps(normal = True), # resolves to @crate_index//:tokio
)
Building the web app with bazel build --platforms=@rules_rust//rust/platform:wasm32 //wasm-app:wasm-app now because we try to compile mio and socket2 for wasm32, which they don't support.
Additional context
I had Claude suggest a fix for this, coming up in a PR next.
Impact
I believe this makes it impossible to build our Rust business logic for Wasm.
Bazel and rules_rust version
- Bazel: 9.1.1
- rules_rust: 0.71.3
Description
crate_universeresolves Cargo features once across the whole workspace and emits a single shared target per crate, used by every target triple. So a feature enabled by any workspace member is enabled for that crate on all triples, and there is no way to drop a feature (or the dependencies it brings in) for a specific triple. Cargo itself resolves features per target and wouldn't do this;crate_universecollapses that distinction.This breaks cross-platform workspaces where a feature is fine on one triple but not another. Concretely: one member (built for a host triple) enables the
netfeature in Tokio. The sharedtokiotarget then hasneton forwasm32-unknown-unknowntoo, pulling inmioandsocket2. They don't build there — even though the Wasm member only usesrt/macros/timefrom Tokio. The Wasm build fails withReproduction steps
Two Rust crates that depend on Tokio with different Cargo features. First crate:
Second crate:
Bazel workspace setup:
Build file:
Building the web app with
bazel build --platforms=@rules_rust//rust/platform:wasm32 //wasm-app:wasm-appnow because we try to compilemioandsocket2forwasm32, which they don't support.Additional context
I had Claude suggest a fix for this, coming up in a PR next.
Impact
I believe this makes it impossible to build our Rust business logic for Wasm.
Bazel and rules_rust version