diff --git a/Cargo.toml b/Cargo.toml index a9f0f59603b01b131042683331077513ff9d441f..9427da76cf27837c763e40f6cc13dc911d75d937 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ description = """ A library for types and bindings to native C functions often found in libc or other common platform libraries. """ +build = "build.rs" [badges] travis-ci = { repository = "rust-lang/libc" } diff --git a/build.rs b/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..aa56ea054506c4f0947ec8aac5a20d62723b8e1a --- /dev/null +++ b/build.rs @@ -0,0 +1,35 @@ +use std::env; +use std::process::Command; +use std::str; + +fn main() { + /* + * If `core::ffi::c_void` exists, libc can just re-export it. Otherwise, it + * must define an incompatible type to retain backwards-compatibility. + */ + if rustc_minor_version().expect("Failed to get rustc version") >= 31 { + println!("cargo:rustc-cfg=core_cvoid"); + } +} + +fn rustc_minor_version() -> Option<u32> { + macro_rules! otry { + ($e:expr) => { + match $e { + Some(e) => e, + None => return None, + } + }; + } + + let rustc = otry!(env::var_os("RUSTC")); + let output = otry!(Command::new(rustc).arg("--version").output().ok()); + let version = otry!(str::from_utf8(&output.stdout).ok()); + let mut pieces = version.split('.'); + + if pieces.next() != Some("rustc 1") { + return None; + } + + otry!(pieces.next()).parse().ok() +} diff --git a/src/lib.rs b/src/lib.rs index 7f8e907aaf7b15088bfe7132993122006d5e32a1..823d36c19c160f4919dd28118a0463a6ffa925fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,17 +108,22 @@ cfg_if! { // On the Switch, we only define some useful universal types for // convenience. Those can be found in the switch.rs file. } else { - - // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable - // more optimization opportunities around it recognizing things like - // malloc/free. - #[repr(u8)] - pub enum c_void { - // Two dummy variants so the #[repr] attribute can be used. - #[doc(hidden)] - __variant1, - #[doc(hidden)] - __variant2, + cfg_if! { + if #[cfg(core_cvoid)] { + pub use core::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable + // more optimization opportunities around it recognizing things like + // malloc/free. + #[repr(u8)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } } pub type int8_t = i8; diff --git a/src/switch.rs b/src/switch.rs index c11379541ea08f95a912f6f5672bf33e344c9228..bb6df388e1564f414c10555511f6522046d043a3 100644 --- a/src/switch.rs +++ b/src/switch.rs @@ -1,17 +1,5 @@ //! Switch C type definitions -// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable -// more optimization opportunities around it recognizing things like -// malloc/free. -#[repr(u8)] -pub enum c_void { - // Two dummy variants so the #[repr] attribute can be used. - #[doc(hidden)] - __variant1, - #[doc(hidden)] - __variant2, -} - pub type int8_t = i8; pub type int16_t = i16; pub type int32_t = i32; @@ -46,3 +34,21 @@ pub type c_char = u8; pub type c_long = i64; pub type c_ulong = u64; pub type wchar_t = u32; + +cfg_if! { + if #[cfg(core_cvoid)] { + pub use core::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +}