Skip to content

Commit a17a91c

Browse files
committed
Fix build on all platforms
This PR fixes the build on all platforms and all Rust version down to the minimum Rust version supported by libc: Rust 1.13.0. The `build.rs` is extended with logic to detect the newer Rust features used by `libc` since Rust 1.13.0: * Rust 1.19.0: `untagged_unions`. APIs using untagged unions are gated on `cfg(libc_unions)` and not available on older Rust versions. * Rust 1.25.0: `repr(align)`. Because `repr(align)` cannot be parsed by older Rust versions, all uses of `repr(align)` are split into `align.rs` and `no_align.rs` modules, which are gated on the `cfg(libc_align)` at the top level. These modules sometimes contain macros that are expanded at the top level to avoid privacy issues (`pub(crate)` is not available in older Rust versions). Closes #1242 . * Rust : `const` `mem::size_of`. These uses are worked around with hardcoded constants on older Rust versions. Also, `repr(packed)` structs cannot automatically `derive()` some traits like `Debug`. These have been moved into `s_no_extra_traits!` and the lint of missing `Debug` implementations on public items is silenced for these. We can manually implement the `extra_traits` for these in a follow up PR. This is tracked in #1243. Also, `extra_traits` does not enable `align` manually anymore. Since `f64::to_bits` is not available in older Rust versions, its usage has been replaced with a `transmute` to an `u64` which is what that method does under the hood. Closes #1232 .
1 parent 8f1acf4 commit a17a91c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+3344
-2583
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ default = ["use_std"]
2727
use_std = []
2828
align = []
2929
rustc-dep-of-std = ['align', 'rustc-std-workspace-core']
30-
extra_traits = ["align"]
30+
extra_traits = []
3131

3232
[workspace]
3333
members = ["libc-test"]

build.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,42 @@ use std::process::Command;
33
use std::str;
44

55
fn main() {
6-
/*
7-
* If `core::ffi::c_void` exists, libc can just re-export it. Otherwise, it
8-
* must define an incompatible type to retain backwards-compatibility.
9-
*/
10-
if rustc_minor_version().expect("Failed to get rustc version") >= 30 {
11-
println!("cargo:rustc-cfg=core_cvoid");
6+
let rustc_minor_ver =
7+
rustc_minor_version().expect("Failed to get rustc version");
8+
let rustc_dep_of_std =
9+
std::env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok();
10+
let align_cargo_feature = std::env::var("CARGO_FEATURE_ALIGN").is_ok();
11+
12+
// Rust >= 1.15 supports private module use:
13+
if rustc_minor_ver >= 15 || rustc_dep_of_std {
14+
println!("cargo:rustc-cfg=libc_priv_mod_use");
15+
}
16+
17+
// Rust >= 1.19 supports unions:
18+
if rustc_minor_ver >= 19 || rustc_dep_of_std {
19+
println!("cargo:rustc-cfg=libc_union");
20+
}
21+
22+
// Rust >= 1.24 supports const mem::size_of:
23+
if rustc_minor_ver >= 24 || rustc_dep_of_std {
24+
println!("cargo:rustc-cfg=libc_const_size_of");
25+
}
26+
27+
// Rust >= 1.25 supports repr(align):
28+
if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature {
29+
println!("cargo:rustc-cfg=libc_align");
30+
}
31+
32+
// Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it.
33+
// Otherwise, it defines an incompatible type to retaining
34+
// backwards-compatibility.
35+
if rustc_minor_ver >= 30 || rustc_dep_of_std {
36+
println!("cargo:rustc-cfg=libc_core_cvoid");
37+
}
38+
39+
// Rust >= 1.33 supports repr(packed(N))
40+
if rustc_minor_ver >= 33 || rustc_dep_of_std {
41+
println!("cargo:rustc-cfg=libc_packedN");
1242
}
1343
}
1444

src/cloudabi/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,15 @@ cfg_if! {
316316
}
317317

318318
cfg_if! {
319-
if #[cfg(core_cvoid)] {
320-
pub use core::ffi::c_void;
319+
if #[cfg(libc_core_cvoid)] {
320+
pub use ::ffi::c_void;
321321
} else {
322322
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help
323323
// enable more optimization opportunities around it recognizing things
324324
// like malloc/free.
325325
#[repr(u8)]
326326
#[allow(missing_copy_implementations)]
327+
#[allow(missing_debug_implementations)]
327328
pub enum c_void {
328329
// Two dummy variants so the #[repr] attribute can be used.
329330
#[doc(hidden)]

src/fuchsia/align.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
macro_rules! expand_align {
2+
() => {
3+
s! {
4+
#[cfg_attr(
5+
any(
6+
target_pointer_width = "32",
7+
target_arch = "x86_64"
8+
),
9+
repr(align(4)))]
10+
#[cfg_attr(
11+
not(any(
12+
target_pointer_width = "32",
13+
target_arch = "x86_64"
14+
)),
15+
repr(align(8)))]
16+
pub struct pthread_mutexattr_t {
17+
size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
18+
}
19+
20+
#[cfg_attr(target_pointer_width = "32",
21+
repr(align(4)))]
22+
#[cfg_attr(target_pointer_width = "64",
23+
repr(align(8)))]
24+
pub struct pthread_rwlockattr_t {
25+
size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T],
26+
}
27+
28+
#[repr(align(4))]
29+
pub struct pthread_condattr_t {
30+
size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
31+
}
32+
}
33+
34+
s_no_extra_traits! {
35+
#[allow(missing_debug_implementations)]
36+
#[cfg_attr(all(target_pointer_width = "32",
37+
any(target_arch = "arm",
38+
target_arch = "x86_64")),
39+
repr(align(4)))]
40+
#[cfg_attr(any(target_pointer_width = "64",
41+
not(any(target_arch = "arm",
42+
target_arch = "x86_64"))),
43+
repr(align(8)))]
44+
pub struct pthread_mutex_t {
45+
size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
46+
}
47+
48+
#[allow(missing_debug_implementations)]
49+
#[cfg_attr(all(target_pointer_width = "32",
50+
any(target_arch = "arm",
51+
target_arch = "x86_64")),
52+
repr(align(4)))]
53+
#[cfg_attr(any(target_pointer_width = "64",
54+
not(any(target_arch = "arm",
55+
target_arch = "x86_64"))),
56+
repr(align(8)))]
57+
pub struct pthread_rwlock_t {
58+
size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
59+
}
60+
61+
#[allow(missing_debug_implementations)]
62+
#[cfg_attr(target_pointer_width = "32",
63+
repr(align(4)))]
64+
#[cfg_attr(target_pointer_width = "64",
65+
repr(align(8)))]
66+
#[cfg_attr(target_arch = "x86",
67+
repr(align(4)))]
68+
#[cfg_attr(not(target_arch = "x86"),
69+
repr(align(8)))]
70+
pub struct pthread_cond_t {
71+
size: [u8; ::__SIZEOF_PTHREAD_COND_T],
72+
}
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)