windows: expose cfg for 64-bit time_t#5062
Conversation
08f37e4 to
137efa8
Compare
This comment has been minimized.
This comment has been minimized.
137efa8 to
1c220d3
Compare
This comment has been minimized.
This comment has been minimized.
1c220d3 to
035eff8
Compare
This comment has been minimized.
This comment has been minimized.
035eff8 to
fafb602
Compare
This comment has been minimized.
This comment has been minimized.
fafb602 to
622c7d8
Compare
This comment has been minimized.
This comment has been minimized.
622c7d8 to
bbd9d2c
Compare
This comment has been minimized.
This comment has been minimized.
bbd9d2c to
099bc00
Compare
This comment has been minimized.
This comment has been minimized.
099bc00 to
065ec82
Compare
This comment has been minimized.
This comment has been minimized.
065ec82 to
0d9de25
Compare
This comment has been minimized.
This comment has been minimized.
0d9de25 to
7d899e8
Compare
This comment has been minimized.
This comment has been minimized.
7d899e8 to
b9a9de4
Compare
This comment has been minimized.
This comment has been minimized.
b9a9de4 to
ae099ec
Compare
This comment has been minimized.
This comment has been minimized.
ae099ec to
dd02b72
Compare
|
@rustbot ready |
| // 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. `_USE_32BIT_TIME_T` in Windows. |
There was a problem hiding this comment.
It shouldn't, right? That should only be applicable on win-msvc, and on MSVC targets time_t is already always 64 bits. I believe this should only affect i686-win-gnu, which uses the same _TIME_BITS=64.
There was a problem hiding this comment.
That's not right. My comment is also wrong. Let me clarify.
In both MSVC and MinGW headers time_t is always 64-bit. In both of them one can use _USE_32BIT_TIME_T to get a 32-bits time_t. The _TIME_BITS feature test macro is sort of supported on MinGW. Though it's useless. It's only checked before checking that _USE_32BIT_TIME_T is defined [1].
What we expose is wrong. This PR is more of a bugfix on our side.
There was a problem hiding this comment.
What do you mean by useless? It appears to control what time_t is via _USE_32BIT_TIME_T https://github.com/mingw-w64/mingw-w64/blob/31bd54ab7d5fe03c67ed2bb1a57e531b9c7f8cc4/mingw-w64-headers/crt/time.h#L52-L59
There was a problem hiding this comment.
I'm referring to _TIME_BITS.
| (gnu && i686).then(|| { | ||
| env::var("CARGO_CFG_LIBC_UNSTABLE_GNU_TIME_BITS") | ||
| .map_err(|_| ()) | ||
| .and_then(|val| val.parse::<usize>().map_err(|_| ())) | ||
| .and_then(|v| (v == 64).then_some("gnu_time_bits64").ok_or(())) | ||
| .map(|op| _ = cfg.cfg(op, None)) | ||
| .unwrap_or_default() | ||
| }); |
There was a problem hiding this comment.
There's no need to use then when there is no return value, if is more clear. But this can be simplified anyway:
if let Ok(tb) = env::var("CARGO_CFG_LIBC_UNSTABLE_GNU_TIME_BITS") {
assert!(
tb == "64" || tb == "32",
"Invalid value for libc_unstable_gnu_time_bits. Must be 32, 64 or unset"
);
if gnu && i686 && tb == "64" {
cfg.cfg("gnu_time_bits64", None);
}
}Do we need a cfg.define here? The other instances of CARGO_CFG_LIBC_UNSTABLE_GNU_TIME_BITS have one.
There was a problem hiding this comment.
We don't. Windows with GNU (under MinGW) has the same behavior as MSVC. It exposes a 64-bit time_t by default. The feature test macro to use a 32-bit time_t is also the same as in MSVC.
Recall this cfg is meant as a bugfix to faulty bindings in the libc crate. time_t is currently 32-bits in main when in Windows x86 with GNU. This doesn't match MinGW headers. We just so happen to be "reusing" gnu_time_bits64.
_TIME_BITS is incompatible with _USE_32BIT_TIME_T in MinGW. The former is sort of supported. They check it's not defined when checking for the latter [1].
7b9905e to
f4ccd58
Compare
This comment has been minimized.
This comment has been minimized.
f4ccd58 to
4e34e51
Compare
This comment has been minimized.
This comment has been minimized.
Adds a test to ensure the changes in rust-lang#5062 are correct. The test ensures the wrong definition is kept on stable. It will use the right bit width in the following cases. - Under targets other than x86 with GNU. - If the `gnu_time_bits64` `cfg` is set.
c268685 to
647bde5
Compare
This comment has been minimized.
This comment has been minimized.
4bc0c62 to
0247682
Compare
|
Seems done. We don't check for @rustbot ready |
Adds a test to ensure the changes in rust-lang#5062 are correct. The test ensures the wrong definition is kept on stable. It will use the right bit width in the following cases. - Under targets other than x86 with GNU. - If the `gnu_time_bits64` `cfg` is set.
c47fb60 to
4a1d9ac
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
4dbde24 to
50299b1
Compare
|
I had to add a I'm not sure if this is the way to go. |
| let redirect_time_t = if gnu && i686 { | ||
| if let Ok(v) = env::var("CARGO_CFG_LIBC_UNSTABLE_GNU_TIME_BITS") { | ||
| assert_matches!( | ||
| v.as_str(), | ||
| "32" | "64", | ||
| "Invalid value for `libc_unstable_gnu_time_bits`. Must be 32, 64 or unset." | ||
| ); | ||
|
|
||
| if v == "64" { | ||
| cfg.cfg("gnu_time_bits64", None); | ||
| println!("cargo::rustc-cfg=gnu_time_bits64"); | ||
| true | ||
| } else { | ||
| false | ||
| } | ||
| } else { | ||
| false | ||
| } | ||
| } else { | ||
| false | ||
| }; |
There was a problem hiding this comment.
Could replace the false chaining with:
let tb_env = env::var("CARGO_CFG_LIBC_UNSTABLE_GNU_TIME_BITS");
let redirect_time_t = match tb_env {
Ok(tb) if tb == "64" => true,
Ok(tb) if tb == "32" => false,
Ok(x) => panic!("Invalid value`{x}` for ... "),
Err(_) => false,
};
println!("rustc-check-cfg...");
if redirect_time_t {
println!(...);
cfg.cfg(...);
}A name like win32_time64 would be more descriptive than redirect_time_t.
| // Corresponds to `_TIME_BITS=64` in glibc. Also used in Windows to fix | ||
| // faulty `time_t` bindings. | ||
| "gnu_time_bits64", |
There was a problem hiding this comment.
Try to be more precise with wording like faulty/wrong/broken. In this case there should be nothing broken in Rust since the link name fix merged, it's just a mismatch to what users get on C. (Applies to the commit message and a few other PRs too).
Also 64-bit time_t wasn't even always an option until last year mingw-w64/mingw-w64@fe21b7e and uclibc a few years before that - libc's bindings just happen to predate that. (Even glibc and musl support didn't fully exist until ~2020.)
| "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 && !redirect_time_t => true, |
There was a problem hiding this comment.
I think you may be able to delete the time_t exclusion entirely with:
if i686 && !redirect_time_t {
cfg.define("_TIME_BITS", Some("32"));
}There was a problem hiding this comment.
Doesn't seem like it. It may be that the MinGW pre-defined macros target the x86_64 host even if the binary targets x86. That would make the conditional in 1 evaluate false.
Footnotes
4bcc1a0 to
618c6b8
Compare
Use `gnu_time_bits64` on Windows x86 GNU to expose a 64-bit `time_t`. `time_t` is always 64-bits on Windows. The target environment matters not. There's a feature test macro to make it 32-bits wide. In `libc` we expose it as 32-bits in Windows x86 GNU. This is not the same default as in C. This `cfg` exposes the same default as in C.
2838970 to
fc36273
Compare
Description
Under Windows GNU x86,
time_tdoesn't have the right size and alignment. This is a backwards-incompatible change, so for folks to experiment on stable, acfghas been exposed to allow exposing a 64-bittime_tinstead. Tests don't fail because we still skiptime_tand records containing some value of such type whenever we're under this target platform/environment.In #5059, we address the issue with routines involving
time_tvalues by making them link to their 32-bit symbols on that platform/environment.This should allow not breaking existing code (even though incorrect,) while still allowing new code to experiment with correct size/alignment for
time_tvalues. Thecfgtries to follow the new practices introduced in #4977.An additional job was not added to the test matrix in CI because it was instead introduced as part of the tests in
ci/run.shthat run only under 32-bit machine word and GNU-hosted targets.Sources
None, if any the same as #5032 as this stems from it.
Checklist
libc-test/semverhave been updated*LASTor*MAXare included (see #3131)cd libc-test && cargo test --target mytarget); especially relevant for platforms that may not be checked in CI@rustbot label +stable-nominated