Skip to content

Without getrandom feature flag forwarding, wasm users builds could break on minor rand update #1694

@michaelkirk

Description

@michaelkirk

My wasm32-unknown-unknown build is working by following the documented suggestion to add an explicit dependency on getrandom in my application crates. Something like this:

[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
getrandom = { version = "0.3.4", features = ["wasm_js"] }

This is unsatisfying in a couple ways (but maybe it's the least worst?):

Firstly, since our crate has some browser usage, we want to be sure our lib crate builds on wasm32-unknown-unknown. Since it's a lib crate, not an application crate, the least worst solution I could find in the spirit of the official documentation would be to introduce a binary (application) crate for the sole purpose of testing our libraries wasm32 compatibility. That's doable, but a little annoying. Is there a better way?

Secondly, since getrandom is a private dependency, rand can now do a major (in the semver sense) release of getrandom without needing a corresponding major semver bump in rand. This was one of the motivations mentioned when making getrandom non-public in #1537

So one day when getrandom releases a major update (say 0.4) and rand updates internally and does a (semver) minor release (say to 0.8.x), our wasm32 users builds will break again, until they update their getrandom dependency in Cargo.toml to something like:

  [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
- getrandom = { version = "0.3.4", features = ["wasm_js"] }
+ getrandom = { version = "0.4.0", features = ["wasm_js"] } # assuming the getrandom feature flag doesn't change

It's a bit rough, right? (I assume you have your reasons!)

One alternative would be to restore something like the pass-through flag getrandom?/js_wasm feature, which was intentionally removed in #886

The reason originally listed for its removal.

Since this is currently the only reason we depend on the getrandom crate directly, this allows us to remove the getrandom_package rename hack, thus also clearing up #881.

If I'm understanding correctly, the rename hack has meanwhile been solved by Rust 1.60 dep:foo syntax, released in April 2022.

Elsewhere I've seen concerns about Cargo.lock bloat and broken builds. I'm not sure if the situation there has improved. I would guess Cargo bloat has not improved. I'm not aware of what the broken builds were, so I have no idea if the situation has improved there.

At the moment I'm considering "solving" this for our users, by pinning our own app to a major version of getrandom:

[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
getrandom = { version = "0.4.0", features = ["wasm_js"] } # assuming the getrandom feature flag doesn't change
   let mut rng = match seed {
        Some(s) => StdRng::seed_from_u64(s),
        #[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
        None => {
            let mut seed = [0u8; 32];
            getrandom::fill(&mut seed)?;
            StdRng::from_seed(seed)
        },
        #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
        None => StdRng::from_os_rng(),
    };

That way if rand bumps its internal private usage of getrandom, we don't have to worry about it breaking our users builds. Do you see any concerns with that approach?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions