From e995050cdfada8c503ee1f8f4ebf100cebaeb127 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 20 Sep 2026 16:26:51 -0500 Subject: [PATCH 1/2] uclibc: Replace `linux_time_bits64` with a new `uclibc32_time64` cfg `linux_time_bits64` should correlate to the kernel's `__USE_TIME_BITS64`, which is set on both 32- and 64-bit platforms where `time_t` is 64 bits. The uclibc version of this config is `UCLIBC_USE_TIME64` which is only set on 32-bit platforms. Split this up by introducing `uclibc32_time64` to closer match `UCLIBC_USE_TIME64`. As an effect, setting `libc_unstable_uclibc_time64` no longer crashes builds for 64-bit uclibc targets. The setup also closer matches what is done for GNU targets. Note that `linux_time_bits64` is not actually the "64-bit time_t on any platform" yet that the kernel's version is, so it still isn't set on 64-bit platforms after this change. * `UCLIBC_USE_TIME64` definition: https://github.com/wbx-github/uclibc-ng/blob/3f2ef085d8455a13fcdc4d4d473c0385dd65d55e/extra/Configs/Config.in#L1036-L1055 * Implication of `__USE_TIME_BITS64`: https://github.com/wbx-github/uclibc-ng/blob/3f2ef085d8455a13fcdc4d4d473c0385dd65d55e/include/features.h#L458-L460 * Entrypoint for 64-bit `time_t`: https://github.com/wbx-github/uclibc-ng/blob/3f2ef085d8455a13fcdc4d4d473c0385dd65d55e/libc/sysdeps/linux/common/bits/typesizes.h#L50-L54 * Arm `struct shimd_ds`: https://github.com/wbx-github/uclibc-ng/blob/3f2ef085d8455a13fcdc4d4d473c0385dd65d55e/libc/sysdeps/linux/arm/bits/shm.h#L48-L69 --- build.rs | 32 +++++++++++++++++---- libc-test/build/main.rs | 8 ++++-- src/unix/linux_like/linux/uclibc/arm/mod.rs | 6 ++-- src/unix/linux_like/linux/uclibc/mod.rs | 2 +- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/build.rs b/build.rs index b3df76b41eda..faa5a33fb293 100644 --- a/build.rs +++ b/build.rs @@ -54,6 +54,9 @@ enum Cfg { /// transition to 64-bit `time_t` and thus need `__*_time64` redirects. Implies `musl_v1_2` /// and 32-bit arch. MuslRedirTime64, + /// Corresponds to the `UCLIBC_USE_TIME64` config / `__UCLIBC_USE_TIME64__` define. Indicates + /// that `*time64` syscalls should be used. Implies 32-bit. + Uclibc32Time64, } const ALLOWED_CFGS: &[Cfg] = &[ @@ -76,6 +79,7 @@ const ALLOWED_CFGS: &[Cfg] = &[ Cfg::MuslV1_2, Cfg::Musl32Time64, Cfg::MuslRedirTime64, + Cfg::Uclibc32Time64, ]; impl fmt::Display for Cfg { @@ -100,6 +104,7 @@ impl fmt::Display for Cfg { Cfg::MuslV1_2 => "musl_v1_2", Cfg::Musl32Time64 => "musl32_time64", Cfg::MuslRedirTime64 => "musl_redir_time64", + Cfg::Uclibc32Time64 => "uclibc32_time64", }) } } @@ -262,12 +267,6 @@ fn main() { } } - let uclibc_time64_env = env_flag("CARGO_CFG_LIBC_UNSTABLE_UCLIBC_TIME64"); - let uclibc_time64 = target_env == "uclibc" && uclibc_time64_env; - if uclibc_time64 { - cfgs.push(Cfg::LinuxTimeBits64); - } - let mut gnu_tb_env = env::var("CARGO_CFG_LIBC_UNSTABLE_GNU_TIME_BITS"); // FIXME: remove these fallbacks in a few releases @@ -314,6 +313,17 @@ fn main() { cfgs.push(Cfg::GnuTimeBits64); } + let uclibc_time64_env = env_flag("CARGO_CFG_LIBC_UNSTABLE_UCLIBC_TIME64"); + let uclibc = target_env == "uclibc"; + let uclibc32_time64 = uclibc && target_ptr_width == "32" && uclibc_time64_env; + + if uclibc32_time64 { + if target_os == "linux" { + cfgs.push(Cfg::LinuxTimeBits64); + } + cfgs.push(Cfg::Uclibc32Time64); + } + // On CI: deny all warnings if libc_ci { cfgs.push(Cfg::LibcDenyWarnings); @@ -492,6 +502,16 @@ fn validate_cfg(list: &[Cfg], target_env: &str, target_os: &str, target_ptr_widt "{cfg:?} set on non-musl1.2 platform" ) } + Cfg::Uclibc32Time64 => { + assert_eq!(target_env, "uclibc", "{cfg:?} set on non-gnu platform"); + assert_eq!(target_ptr_width, "32", "{cfg:?} set on non-32-bit platform"); + if target_os == "linux" { + assert!( + list.contains(&Cfg::LinuxTimeBits64), + "missing 64-bit time_t Linux config" + ) + } + } } } } diff --git a/libc-test/build/main.rs b/libc-test/build/main.rs index c6b1a271e522..1d4dca435c87 100755 --- a/libc-test/build/main.rs +++ b/libc-test/build/main.rs @@ -3995,10 +3995,14 @@ fn test_linux(t: &Target) { } } - let uclibc_use_time64 = env_flag("CARGO_CFG_LIBC_UNSTABLE_UCLIBC_TIME64"); - if uclibc && uclibc_use_time64 { + let uclibc_time64_env = env_flag("CARGO_CFG_LIBC_UNSTABLE_UCLIBC_TIME64"); + let uclibc32_time64 = uclibc && p32 && uclibc_time64_env; + + if uclibc32_time64 { cfg.cfg("linux_time_bits64", None); + cfg.cfg("uclibc32_time64", None); } + cfg.define("_GNU_SOURCE", None) // This macro re-defines fscanf,scanf,sscanf to link to the symbols that are // deprecated since glibc >= 2.29. This allows Rust binaries to link against diff --git a/src/unix/linux_like/linux/uclibc/arm/mod.rs b/src/unix/linux_like/linux/uclibc/arm/mod.rs index 25a586a9ec11..610861f89168 100644 --- a/src/unix/linux_like/linux/uclibc/arm/mod.rs +++ b/src/unix/linux_like/linux/uclibc/arm/mod.rs @@ -220,13 +220,13 @@ s! { pub shm_perm: crate::ipc_perm, pub shm_segsz: size_t, pub shm_atime: crate::time_t, - #[cfg(not(linux_time_bits64))] + #[cfg(not(uclibc32_time64))] __unused1: Padding, pub shm_dtime: crate::time_t, - #[cfg(not(linux_time_bits64))] + #[cfg(not(uclibc32_time64))] __unused2: Padding, pub shm_ctime: crate::time_t, - #[cfg(not(linux_time_bits64))] + #[cfg(not(uclibc32_time64))] __unused3: Padding, pub shm_cpid: crate::pid_t, pub shm_lpid: crate::pid_t, diff --git a/src/unix/linux_like/linux/uclibc/mod.rs b/src/unix/linux_like/linux/uclibc/mod.rs index e4886da53e3d..a339d669e7bc 100644 --- a/src/unix/linux_like/linux/uclibc/mod.rs +++ b/src/unix/linux_like/linux/uclibc/mod.rs @@ -14,7 +14,7 @@ pub type __priority_which_t = c_uint; cfg_if! { // Set `--cfg=libc_unstable_uclibc_time64` in RUSTFLAGS if your uClibc has 64-bit `time_t`. - if #[cfg(linux_time_bits64)] { + if #[cfg(uclibc32_time64)] { pub type time_t = i64; pub type suseconds_t = i64; } else { From fd5594cb7a97957deaf14ffbc2b8f5a899658823 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 20 Sep 2026 16:40:45 -0500 Subject: [PATCH 2/2] ci: Check building uclibc with `libc_unstable_uclibc_time64` --- ci/verify-build.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ci/verify-build.py b/ci/verify-build.py index 23010dcdceb7..065643d42a37 100755 --- a/ci/verify-build.py +++ b/ci/verify-build.py @@ -420,6 +420,10 @@ def test_target(cfg: Cfg, target: Target) -> TargetResult: # Check with breaking changes from musl, including 64-bit time_t on 32-bit run(cmd, rustflags=f"{rustflags} --cfg=libc_unstable_musl_v1_2") + if "uclibc" in target_env: + # Equivalent of UCLIBC_USE_TIME64 on 32-bit targets, ignored on 64-bit + run(cmd, rustflags=f"{rustflags} --cfg=libc_unstable_uclibc_time64") + # Test again without default features, i.e. without `std` run([*cmd, "--no-default-features"], rustflags=rustflags) run([*cmd, "--no-default-features", "--features=extra_traits"], rustflags=rustflags)