Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,6 @@ jobs:
web:
name: ${{ matrix.target.description }} ${{ matrix.feature.description }} ${{ matrix.atomic.description }}
runs-on: ubuntu-24.04
env:
RUSTFLAGS: --cfg getrandom_backend="wasm_js" ${{ matrix.atomic.flags }}
strategy:
fail-fast: false
matrix:
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,13 @@ jobs:
- {
description: Web,
version: stable,
flags: '-Dwarnings --cfg getrandom_backend="wasm_js"',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still want -Dwarnings (unless substituted below)

args: '--features=std,sys_rng,wasm_js',
}
- {
description: Web with Atomics,
version: nightly,
components: rust-src,
flags: '-Dwarnings --cfg getrandom_backend="wasm_js" -Ctarget-feature=+atomics,+bulk-memory',
flags: '-Dwarnings -Ctarget-feature=+atomics,+bulk-memory',
args: '--features=std,sys_rng,wasm_js -Zbuild-std=panic_abort,std',
}
steps:
Expand Down
12 changes: 9 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ features = ["std", "sys_rng"]
std = []

# Optional backend: wasm_js
#
# This flag enables the wasm_js backend and uses it by default on wasm32 where
# the target_os is unknown. The getrandom_backend cfg may override this.
# WARNING: It is highly recommended to enable this feature only for binary crates and tests,
# i.e. avoid unconditionally enabling it in library crates.
#
# WARNING: This feature SHOULD be enabled ONLY for binary crates and tests. In other words,
# avoid enabling it in library crates whether unconditionally or gated on a crate feature.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or gated on a crate feature

I see no hard reason not to have a "forwarding" feature flag (e.g. wasm_js = ["getrandom/wasm_js"]).

I know you don't like this pattern, but I don't think directing users like this will work particularly well.

I suggest we keep our advice direct and minimally opinionated:

We recommend against enabling this feature in libraries (except for tests) since it is known to break some non-Web WASM builds and further since the usage of wasm-bindgen causes significant bloat to Cargo.lock (on all targets).

# By not following this recommendation you may break builds for users targeting non-Web WASM.
#
# The only exception to this rule: if your crate already unconditionally depends on `wasm-bindgen`
# or `js-sys` on "unknown" WASM targets then it's acceptable to enable this feature unconditionally.
wasm_js = ["dep:wasm-bindgen", "dep:js-sys"]

# Provide SysRng over rand_core
Expand Down Expand Up @@ -84,7 +90,7 @@ wasm-bindgen-test = "0.3"
[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [
'cfg(getrandom_backend, values("custom", "efi_rng", "rdrand", "rndr", "linux_getrandom", "linux_raw", "wasm_js", "windows_legacy", "unsupported"))',
'cfg(getrandom_backend, values("custom", "efi_rng", "rdrand", "rndr", "linux_getrandom", "linux_raw", "windows_legacy", "unsupported"))',
'cfg(getrandom_msan)',
'cfg(getrandom_test_linux_fallback)',
'cfg(getrandom_test_linux_without_fallback)',
Expand Down
50 changes: 24 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,28 @@ fn get_random_u128() -> Result<u128, getrandom::Error> {

Pull Requests that add support for new targets to `getrandom` are always welcome.

### WebAssembly support

This crate fully supports the [WASI] and [Emscripten] targets. However,
the `wasm32-unknown-unknown` target (i.e. the target used by `wasm-pack`)
is not automatically supported since, from the target name alone, we cannot deduce
which JavaScript interface should be used (or if JavaScript is available at all).

We do not include support for this target in the default configuration because our JS backend
(supporting web browsers, web workers and Node.js v19 or later) requires [`wasm-bindgen`],
**bloating `Cargo.lock`** and **potentially breaking builds** on non-web WASM platforms.

To enable `getrandom`'s functionality on `wasm32-unknown-unknown` using
[`Crypto.getRandomValues`] via [`wasm-bindgen`], enable the `wasm_js` crate feature.

WARNING: This feature SHOULD be enabled ONLY for binary crates and tests. In other words,
avoid enabling it in library crates whether unconditionally or gated on a crate feature.
By not following this recommendation you may break builds for users targeting non-Web WASM
even when a different backend is selected via `getrandom_backend`.

The only exception to this rule: if your crate already unconditionally depends on `wasm-bindgen`
or `js-sys` on "unknown" WASM targets then it's acceptable to enable this feature unconditionally.

### Opt-in backends

`getrandom` also provides optional (opt-in) backends, which allow users to customize the source
Expand All @@ -84,7 +106,6 @@ of randomness based on their specific needs:
| `linux_raw` | Linux, Android | `*‑linux‑*` | Same as `linux_getrandom`, but uses raw `asm!`-based syscalls instead of `libc`.
| `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction
| `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register
| `wasm_js` | Web Browser, Node.js | `wasm32‑unknown‑unknown`, `wasm32v1-none` | [`Crypto.getRandomValues`]. Enabled by the `wasm_js` feature ([see below](#webassembly-support)).
| `efi_rng` | UEFI | `*-unknown‑uefi` | [`EFI_RNG_PROTOCOL`] with `EFI_RNG_ALGORITHM_RAW` (requires `std` and Nightly compiler)
| `windows_legacy` | Windows | `*-windows-*` | [`RtlGenRandom`]
| `custom` | All targets | `*` | User-provided custom implementation (see [custom backend])
Expand All @@ -94,8 +115,8 @@ Opt-in backends can be enabled using the `getrandom_backend` configuration flag.
The flag can be set either by specifying the `rustflags` field in [`.cargo/config.toml`]:
```toml
# It's recommended to set the flag on a per-target basis:
[target.wasm32-unknown-unknown]
rustflags = ['--cfg', 'getrandom_backend="wasm_js"']
[target.'cfg(target_os = "linux")']
rustflags = ['--cfg', 'getrandom_backend="linux_getrandom"']
```

Or by using the `RUSTFLAGS` environment variable:
Expand Down Expand Up @@ -124,29 +145,6 @@ Note that the raw syscall backend may be slower than backends based on `libc::ge
e.g. it does not implement vDSO optimizations and on `x86` it uses the infamously slow
`int 0x80` instruction to perform syscall.

### WebAssembly support

This crate fully supports the [WASI] and [Emscripten] targets. However,
the `wasm32-unknown-unknown` target (i.e. the target used by `wasm-pack`)
is not automatically supported since, from the target name alone, we cannot deduce
which JavaScript interface should be used (or if JavaScript is available at all).

We do not include support for this target in the default configuration because
our JS backend (supporting web browsers, web workers and Node.js v19 or later)
requires [`wasm-bindgen`], **bloating `Cargo.lock`** and
**potentially breaking builds** on non-web WASM platforms.

To enable `getrandom`'s functionality on `wasm32-unknown-unknown` using the Web
Crypto methods [described above][opt-in] via [`wasm-bindgen`], enable the
`wasm_js` feature flag. Setting `RUSTFLAGS='--cfg getrandom_backend="wasm_js"'`
is allowed but is no longer required and does nothing (it was required in a
prior version of this crate).

WARNING: enabling the `wasm_js` feature will bloat `Cargo.lock` on all platforms
(where [`wasm-bindgen`] is not an existing dependency) and is known to cause
build issues on some non-web WASM platforms, even when a different backend is
selected via `getrandom_backend`.

### Custom backend

If this crate does not support your target out of the box or you have to use
Expand Down
16 changes: 1 addition & 15 deletions src/backends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,6 @@ cfg_if! {
} else if #[cfg(getrandom_backend = "windows_legacy")] {
mod windows_legacy;
pub use windows_legacy::*;
} else if #[cfg(getrandom_backend = "wasm_js")] {
cfg_if! {
if #[cfg(feature = "wasm_js")] {
mod wasm_js;
pub use wasm_js::*;
} else {
compile_error!(concat!(
"The \"wasm_js\" backend requires the `wasm_js` feature \
for `getrandom`. For more information see: \
https://docs.rs/getrandom/", env!("CARGO_PKG_VERSION"), "/#webassembly-support"
));
}
}
} else if #[cfg(getrandom_backend = "unsupported")] {
mod unsupported;
pub use unsupported::*;
Expand Down Expand Up @@ -187,8 +174,7 @@ cfg_if! {
} else {
compile_error!(concat!(
"The wasm32-unknown-unknown targets are not supported by default; \
you may need to enable the \"wasm_js\" configuration flag. Note \
that enabling the `wasm_js` feature flag alone is insufficient. \
you may need to enable the \"wasm_js\" crate feature. \
For more information see: \
https://docs.rs/getrandom/", env!("CARGO_PKG_VERSION"), "/#webassembly-support"
));
Expand Down
6 changes: 5 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,11 @@ impl Error {
Error::IOS_RANDOM_GEN => "SecRandomCopyBytes: iOS Security framework failure",
#[cfg(all(windows, target_vendor = "win7"))]
Error::WINDOWS_RTL_GEN_RANDOM => "RtlGenRandom: Windows system function failure",
#[cfg(all(feature = "wasm_js", getrandom_backend = "wasm_js"))]
#[cfg(all(
feature = "wasm_js",
target_arch = "wasm32",
any(target_os = "unknown", target_os = "none")
))]
Error::WEB_CRYPTO => "Web Crypto API is unavailable",
#[cfg(target_os = "vxworks")]
Error::VXWORKS_RAND_SECURE => "randSecure: VxWorks RNG module is not initialized",
Expand Down