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
7 changes: 4 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const ALLOWED_CFGS: &[&str] = &[
"freebsd15",
// Corresponds to `_FILE_OFFSET_BITS=64` in glibc
"gnu_file_offset_bits64",
// Corresponds to `_TIME_BITS=64` in glibc
// Corresponds to `_TIME_BITS=64` in glibc. Also used in x86 Windows with
// GNU to expose a 64-bit `time_t`.
"gnu_time_bits64",
"libc_deny_warnings",
// Corresponds to `__USE_TIME_BITS64` in UAPI
Expand Down Expand Up @@ -144,7 +145,7 @@ fn main() {
}

if target_env == "gnu"
&& target_os == "linux"
&& matches!(target_os.as_str(), "linux" | "windows")
&& target_ptr_width == "32"
&& target_arch != "riscv32"
&& target_arch != "x86_64"
Expand Down Expand Up @@ -173,7 +174,7 @@ fn main() {
let (timebits, filebits) = match (tb_env.as_deref(), fb_env.as_deref()) {
(Ok(_), Ok(_)) => panic!(
"Do not set both libc_unstable_gnu_time_bits and \
libc_unstable_gnu_file_offset_bits"
libc_unstable_gnu_file_offset_bits"
),
(Err(_), Err(_)) => (defaultbits, defaultbits),
(Ok(tb), Err(_)) if tb == "64" => (tb, tb),
Expand Down
19 changes: 18 additions & 1 deletion libc-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,23 @@ fn test_windows(target: &str) {
}
cfg.define("_WIN32_WINNT", Some("0x8000"));

let win_gnu_x86_time64 = match env::var("CARGO_CFG_LIBC_UNSTABLE_GNU_TIME_BITS") {
Ok(v) if v == "64" => true,
Ok(v) if v == "32" => false,
Ok(_) => {
panic!("Invalid value for `libc_unstable_gnu_time_bits`. Must be 32, 64 or unset.");
}
Err(_) => false,
};

// Needed for the Windows `time_t` test.
println!("cargo::rustc-check-cfg=cfg(gnu_time_bits64)");

if i686 && gnu && win_gnu_x86_time64 {
cfg.cfg("gnu_time_bits64", None);
println!("cargo::rustc-cfg=gnu_time_bits64");
}

headers!(
cfg,
"direct.h",
Expand Down Expand Up @@ -841,7 +858,7 @@ fn test_windows(target: &str) {
"SSIZE_T" if !gnu => true,
"ssize_t" if !gnu => true,
// FIXME(windows): The size and alignment of this type are incorrect
"time_t" if gnu && i686 => true,
"time_t" if gnu && i686 && !win_gnu_x86_time64 => true,
_ => false,
});

Expand Down
6 changes: 5 additions & 1 deletion libc-test/tests/windows_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
/// functions that expect it as a parameter.
#[test]
fn test_bitwidth_store() {
if cfg!(all(target_arch = "x86", target_env = "gnu")) {
if cfg!(all(
target_arch = "x86",
target_env = "gnu",
not(gnu_time_bits64),
)) {
assert_eq!(size_of::<libc::time_t>(), 4);
} else {
assert_eq!(size_of::<libc::time_t>(), 8);
Expand Down
14 changes: 12 additions & 2 deletions src/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ pub type clock_t = i32;
pub type errno_t = c_int;

cfg_if! {
if #[cfg(all(target_arch = "x86", target_env = "gnu"))] {
// FIXME(1.0): Windows GNU has 64-bit `time_t` by default. In x86 this is
// wrongly bound.
if #[cfg(all(
target_arch = "x86",
target_env = "gnu",
not(gnu_time_bits64)
))] {
pub type time_t = i32;
} else {
pub type time_t = i64;
Expand Down Expand Up @@ -395,7 +401,11 @@ extern "C" {
// Under Windows x86 with GNU, `time_t` is still 32-bit wide on stable, so
// these routines have to link with their 32-bit variants.
cfg_if! {
if #[cfg(all(target_arch = "x86", target_env = "gnu"))] {
if #[cfg(all(
target_arch = "x86",
target_env = "gnu",
not(gnu_time_bits64),
))] {
#[link_name = "_ctime32"]
pub fn ctime(sourceTime: *const time_t) -> *mut c_char;
#[link_name = "_difftime32"]
Expand Down