bazelbuild / bazelbuild/rules_rust
Cargo features are enabled for all target triples
- Dominant language
- Starlark
- Stars
- 843
- Forks
- 651
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 15
Description
**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:
```toml
[package]
name = "native-app"
version = "0.0.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["net"] }
```
Second crate:
```toml
[package]
name = "wasm-app"
version = "0.0.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["rt", "macros", "time"] }
```
Bazel workspace setup:
```python
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:
```python
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
Contributor guide
Research direction
Start with the crate.from_cargo configuration and all_crate_deps(normal = True) in the reproduction, then trace how Cargo features become the shared @crate_index//:tokio target. Compare that behavior with Cargo's per-target feature resolution. Done means the native and Wasm examples resolve only their target-supported Tokio features and the wasm32 build no longer attempts mio or socket2.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100