Skip to content

Commit cf1f37e

Browse files
authored
windows: always use RtlGenRandom on pre-1.78 Rust versions (#610)
This PR adds detection of Rust compiler version in the build script while compiling the crate for Windows targets. If the version is smaller than 1.78, then we switch to the `windows7` backend for all Windows targets. This is necessary because on those older versions we can not disambiguate between win7 and win10 based on the target triplet.
1 parent 491d9d4 commit cf1f37e

File tree

5 files changed

+63
-5
lines changed

5 files changed

+63
-5
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [0.3.2] - UNRELEASED
8+
9+
### Changed
10+
- Always use `RtlGenRandom` on Windows targets when compiling with pre-1.78 Rust [#610]
11+
12+
[#610]: https://github.com/rust-random/getrandom/pull/610
13+
714
## [0.3.1] - 2025-01-28
815

916
### Fixed
@@ -526,6 +533,8 @@ Publish initial implementation.
526533
## [0.0.0] - 2019-01-19
527534
Publish an empty template library.
528535

536+
[0.3.2]: https://github.com/rust-random/getrandom/compare/v0.3.0...v0.3.2
537+
[0.3.1]: https://github.com/rust-random/getrandom/compare/v0.3.0...v0.3.1
529538
[0.3.0]: https://github.com/rust-random/getrandom/compare/v0.2.15...v0.3.0
530539
[0.2.15]: https://github.com/rust-random/getrandom/compare/v0.2.14...v0.2.15
531540
[0.2.14]: https://github.com/rust-random/getrandom/compare/v0.2.13...v0.2.14

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ libc = { version = "0.2.154", default-features = false }
6767
wasi = { version = "0.14", default-features = false }
6868

6969
# windows7
70-
[target.'cfg(all(windows, not(target_vendor = "win7")))'.dependencies]
70+
[target.'cfg(all(windows, not(target_vendor = "win7"), not(getrandom_windows_legacy)))'.dependencies]
7171
windows-targets = "0.53"
7272

7373
# wasm_js
@@ -83,6 +83,7 @@ level = "warn"
8383
check-cfg = [
8484
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "wasm_js"))',
8585
'cfg(getrandom_msan)',
86+
'cfg(getrandom_windows_legacy)',
8687
'cfg(getrandom_test_linux_fallback)',
8788
'cfg(getrandom_test_linux_without_fallback)',
8889
'cfg(getrandom_test_netbsd_fallback)',

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn get_random_u128() -> Result<u128, getrandom::Error> {
4343
| Target | Target Triple | Implementation
4444
| ------------------ | ------------------ | --------------
4545
| Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
46-
| Windows 10+ | `*‑windows‑*` | [`ProcessPrng`]
46+
| Windows 10+ | `*‑windows‑*` | [`ProcessPrng`] on Rust 1.78+, [`RtlGenRandom`] otherwise
4747
| Windows 7, 8 | `*-win7‑windows‑*` | [`RtlGenRandom`]
4848
| macOS | `*‑apple‑darwin` | [`getentropy`][3]
4949
| iOS, tvOS, watchOS | `*‑apple‑{ios,tvos,watchos}` | [`CCRandomGenerateBytes`]

build.rs

+50-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,57 @@
1-
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't
2-
// supported. Build scripts get cfg() info, even if the cfg is unstable.
1+
use std::{env, ffi::OsString, process::Command};
2+
3+
/// Tries to get the minor version of the Rust compiler in use.
4+
/// If it fails for any reason, returns `None`.
5+
///
6+
/// Based on the `rustc_version` crate.
7+
fn rustc_minor_version() -> Option<u64> {
8+
let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
9+
let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER").filter(|w| !w.is_empty()) {
10+
let mut cmd = Command::new(wrapper);
11+
cmd.arg(rustc);
12+
cmd
13+
} else {
14+
Command::new(rustc)
15+
};
16+
17+
let out = cmd.arg("-vV").output().ok()?;
18+
19+
if !out.status.success() {
20+
return None;
21+
}
22+
23+
let stdout = std::str::from_utf8(&out.stdout).ok()?;
24+
25+
// Assumes that the first line contains "rustc 1.xx.0-channel (abcdef 2025-01-01)"
26+
// where "xx" is the minor version which we want to extract
27+
let mut lines = stdout.lines();
28+
let first_line = lines.next()?;
29+
let minor_ver_str = first_line.split(".").nth(1)?;
30+
minor_ver_str.parse().ok()
31+
}
32+
333
fn main() {
34+
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't
35+
// supported. Build scripts get cfg() info, even if the cfg is unstable.
436
println!("cargo:rerun-if-changed=build.rs");
537
let santizers = std::env::var("CARGO_CFG_SANITIZE").unwrap_or_default();
638
if santizers.contains("memory") {
739
println!("cargo:rustc-cfg=getrandom_msan");
840
}
41+
42+
// Use `RtlGenRandom` on older compiler versions since win7 targets
43+
// were introduced only in Rust 1.78
44+
let target_family = env::var_os("CARGO_CFG_TARGET_FAMILY").and_then(|f| f.into_string().ok());
45+
if target_family.as_deref() == Some("windows") {
46+
/// Minor version of the Rust compiler in which win7 targets were inroduced
47+
const WIN7_INTRODUCED_MINOR_VER: u64 = 78;
48+
49+
match rustc_minor_version() {
50+
Some(minor_ver) if minor_ver < WIN7_INTRODUCED_MINOR_VER => {
51+
println!("cargo:rustc-cfg=getrandom_windows_legacy");
52+
}
53+
None => println!("cargo:warning=Couldn't detect minor version of the Rust compiler"),
54+
_ => {}
55+
}
56+
}
957
}

src/backends.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ cfg_if! {
145145
} else if #[cfg(target_os = "solid_asp3")] {
146146
mod solid;
147147
pub use solid::*;
148-
} else if #[cfg(all(windows, target_vendor = "win7"))] {
148+
} else if #[cfg(all(windows, any(target_vendor = "win7", getrandom_windows_legacy)))] {
149149
mod windows7;
150150
pub use windows7::*;
151151
} else if #[cfg(windows)] {

0 commit comments

Comments
 (0)