Skip to content

Cargo features are enabled for all target triples #4163

Description

@mgeisler

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageThe ticket needs maintainer attention.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions