Summary
libc::localtime_s and libc::gmtime_s for Windows are declared as plain externs (no link_name), e.g. in src/windows/mod.rs:
pub fn localtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> errno_t;
In the UCRT these names are static __inline header wrappers (in time.h) that forward to _localtime64_s/_gmtime64_s; only the underscore-prefixed variants are actual exports of ucrtbase / api-ms-win-crt-time-l1-1-0. Microsoft's docs state localtime_s is implemented as an inline function.
Behavior change
Historically this linked anyway with VS 2022-era import libraries. With Visual Studio 18 toolchains (MSVC 14.50 / 14.51 — which GitHub's windows-latest image now ships), linking any program that calls libc::localtime_s/gmtime_s fails:
error LNK2019: unresolved external symbol localtime_s
error LNK2019: unresolved external symbol gmtime_s
Same code, same libc version, links fine on VS 2022 (14.4x) — the compat objects that used to satisfy these names appear to be gone from the newer import libs.
Repro
On x86_64-pc-windows-msvc with a VS 18 toolchain:
fn main() {
unsafe {
let t: libc::time_t = 0;
let mut tm: libc::tm = core::mem::zeroed();
libc::localtime_s(&mut tm, &t);
}
}
Suggested fix
Declare them with the exported symbol names, matching what the header inline does (libc's Windows time_t is i64, so the 64-bit variants are the right targets):
#[link_name = "_localtime64_s"]
pub fn localtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> errno_t;
#[link_name = "_gmtime64_s"]
pub fn gmtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> errno_t;
Other UCRT declarations that exist only as header inlines may deserve the same audit.
Downstream reports
Summary
libc::localtime_sandlibc::gmtime_sfor Windows are declared as plain externs (nolink_name), e.g. insrc/windows/mod.rs:In the UCRT these names are
static __inlineheader wrappers (intime.h) that forward to_localtime64_s/_gmtime64_s; only the underscore-prefixed variants are actual exports of ucrtbase /api-ms-win-crt-time-l1-1-0. Microsoft's docs state localtime_s is implemented as an inline function.Behavior change
Historically this linked anyway with VS 2022-era import libraries. With Visual Studio 18 toolchains (MSVC 14.50 / 14.51 — which GitHub's
windows-latestimage now ships), linking any program that callslibc::localtime_s/gmtime_sfails:Same code, same libc version, links fine on VS 2022 (14.4x) — the compat objects that used to satisfy these names appear to be gone from the newer import libs.
Repro
On
x86_64-pc-windows-msvcwith a VS 18 toolchain:Suggested fix
Declare them with the exported symbol names, matching what the header inline does (libc's Windows
time_tisi64, so the 64-bit variants are the right targets):Other UCRT declarations that exist only as header inlines may deserve the same audit.
Downstream reports
cargo install; five releases of CI on VS 2022 runners linked fine)