From 63b0d673eaf2a177ff208c5c50999738bdd1bf0d Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 25 Jun 2023 10:24:57 +0200 Subject: [PATCH] Fix ABI compatibility with Emscripten >= 3.1.42 See: https://github.com/emscripten-core/emscripten/pull/19569#issuecomment-1605440414 --- build.rs | 40 +++++++++++++++++++++++++++ src/unix/linux_like/emscripten/mod.rs | 6 ++++ 2 files changed, 46 insertions(+) diff --git a/build.rs b/build.rs index 79bec0ea4c30b..9b64f7b0d20f6 100644 --- a/build.rs +++ b/build.rs @@ -7,6 +7,7 @@ use std::string::String; // need to know all the possible cfgs that this script will set. If you need to set another cfg // make sure to add it to this list as well. const ALLOWED_CFGS: &'static [&'static str] = &[ + "emscripten_new_stat_abi", "freebsd10", "freebsd11", "freebsd12", @@ -69,6 +70,18 @@ fn main() { Some(_) | None => set_cfg("freebsd11"), } + match emcc_version() { + Some((major, minor, patch)) + if (major > 3) + || (major == 3 && minor > 1) + || (major == 3 && minor == 1 && patch >= 42) => + { + set_cfg("emscripten_new_stat_abi") + } + // Non-Emscripten or version < 3.1.42. + Some(_) | None => (), + } + // On CI: deny all warnings if libc_ci { set_cfg("libc_deny_warnings"); @@ -238,6 +251,33 @@ fn which_freebsd() -> Option { } } +fn emcc_version() -> Option<(u32, u32, u32)> { + let output = std::process::Command::new("emcc") + .arg("-dumpversion") + .output() + .ok(); + if output.is_none() { + return None; + } + let output = output.unwrap(); + if !output.status.success() { + return None; + } + + let stdout = String::from_utf8(output.stdout).ok(); + if stdout.is_none() { + return None; + } + let version = stdout.unwrap(); + let mut pieces = version.trim().split('.'); + + let major = pieces.next()?.parse().unwrap(); + let minor = pieces.next()?.parse().unwrap(); + let patch = pieces.next()?.parse().unwrap(); + + Some((major, minor, patch)) +} + fn set_cfg(cfg: &str) { if !ALLOWED_CFGS.contains(&cfg) { panic!("trying to set cfg {}, but it is not in ALLOWED_CFGS", cfg); diff --git a/src/unix/linux_like/emscripten/mod.rs b/src/unix/linux_like/emscripten/mod.rs index 5b947b634c12a..c0d7071840847 100644 --- a/src/unix/linux_like/emscripten/mod.rs +++ b/src/unix/linux_like/emscripten/mod.rs @@ -260,13 +260,16 @@ s! { } pub struct stat { pub st_dev: ::dev_t, + #[cfg(not(emscripten_new_stat_abi))] __st_dev_padding: ::c_int, + #[cfg(not(emscripten_new_stat_abi))] __st_ino_truncated: ::c_long, pub st_mode: ::mode_t, pub st_nlink: ::nlink_t, pub st_uid: ::uid_t, pub st_gid: ::gid_t, pub st_rdev: ::dev_t, + #[cfg(not(emscripten_new_stat_abi))] __st_rdev_padding: ::c_int, pub st_size: ::off_t, pub st_blksize: ::blksize_t, @@ -282,13 +285,16 @@ s! { pub struct stat64 { pub st_dev: ::dev_t, + #[cfg(not(emscripten_new_stat_abi))] __st_dev_padding: ::c_int, + #[cfg(not(emscripten_new_stat_abi))] __st_ino_truncated: ::c_long, pub st_mode: ::mode_t, pub st_nlink: ::nlink_t, pub st_uid: ::uid_t, pub st_gid: ::gid_t, pub st_rdev: ::dev_t, + #[cfg(not(emscripten_new_stat_abi))] __st_rdev_padding: ::c_int, pub st_size: ::off_t, pub st_blksize: ::blksize_t,