Skip to content

Commit 14c8a81

Browse files
committed
Re-export core::ffi::c_void if supported
1 parent 1844a77 commit 14c8a81

File tree

4 files changed

+68
-21
lines changed

4 files changed

+68
-21
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ description = """
1212
A library for types and bindings to native C functions often found in libc or
1313
other common platform libraries.
1414
"""
15+
build = "build.rs"
1516

1617
[badges]
1718
travis-ci = { repository = "rust-lang/libc" }

build.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use std::env;
2+
use std::process::Command;
3+
use std::str;
4+
5+
fn main() {
6+
/*
7+
* If `core::ffi::c_void` exists, libc can just re-export it. Otherwise, it must define an
8+
* incompatible type to retain backwards-compatibility.
9+
*/
10+
if rustc_minor_version().expect("Failed to get rustc version") >= 31 {
11+
println!("cargo:rustc-cfg=core_cvoid");
12+
}
13+
}
14+
15+
fn rustc_minor_version() -> Option<u32> {
16+
macro_rules! otry {
17+
($e:expr) => {
18+
match $e {
19+
Some(e) => e,
20+
None => return None,
21+
}
22+
};
23+
}
24+
25+
let rustc = otry!(env::var_os("RUSTC"));
26+
let output = otry!(Command::new(rustc).arg("--version").output().ok());
27+
let version = otry!(str::from_utf8(&output.stdout).ok());
28+
let mut pieces = version.split('.');
29+
30+
if pieces.next() != Some("rustc 1") {
31+
return None;
32+
}
33+
34+
otry!(pieces.next()).parse().ok()
35+
}

src/lib.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,22 @@ cfg_if! {
108108
// On the Switch, we only define some useful universal types for
109109
// convenience. Those can be found in the switch.rs file.
110110
} else {
111-
112-
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
113-
// more optimization opportunities around it recognizing things like
114-
// malloc/free.
115-
#[repr(u8)]
116-
pub enum c_void {
117-
// Two dummy variants so the #[repr] attribute can be used.
118-
#[doc(hidden)]
119-
__variant1,
120-
#[doc(hidden)]
121-
__variant2,
111+
cfg_if! {
112+
if #[cfg(core_cvoid)] {
113+
pub use core::ffi::c_void;
114+
} else {
115+
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
116+
// more optimization opportunities around it recognizing things like
117+
// malloc/free.
118+
#[repr(u8)]
119+
pub enum c_void {
120+
// Two dummy variants so the #[repr] attribute can be used.
121+
#[doc(hidden)]
122+
__variant1,
123+
#[doc(hidden)]
124+
__variant2,
125+
}
126+
}
122127
}
123128

124129
pub type int8_t = i8;

src/switch.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
//! Switch C type definitions
22
3-
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
4-
// more optimization opportunities around it recognizing things like
5-
// malloc/free.
6-
#[repr(u8)]
7-
pub enum c_void {
8-
// Two dummy variants so the #[repr] attribute can be used.
9-
#[doc(hidden)]
10-
__variant1,
11-
#[doc(hidden)]
12-
__variant2,
3+
cfg_if! {
4+
if #[cfg(core_cvoid)] {
5+
pub use core::ffi::c_void;
6+
} else {
7+
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
8+
// more optimization opportunities around it recognizing things like
9+
// malloc/free.
10+
#[repr(u8)]
11+
pub enum c_void {
12+
// Two dummy variants so the #[repr] attribute can be used.
13+
#[doc(hidden)]
14+
__variant1,
15+
#[doc(hidden)]
16+
__variant2,
17+
}
18+
}
1319
}
1420

1521
pub type int8_t = i8;

0 commit comments

Comments
 (0)