From 79c80c4ec44a470e3b9cb194da19a23a2ddb2f0a Mon Sep 17 00:00:00 2001 From: Isaac Woods Date: Mon, 17 Sep 2018 19:33:52 +0100 Subject: [PATCH] Re-export core::ffi::c_void if supported --- Cargo.toml | 1 + build.rs | 35 +++++++++++++++++++++++++++++++++++ src/lib.rs | 27 ++++++++++++++++----------- src/switch.rs | 30 ++++++++++++++++++------------ 4 files changed, 70 insertions(+), 23 deletions(-) create mode 100644 build.rs diff --git a/Cargo.toml b/Cargo.toml index a9f0f596..9427da76 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 00000000..aa56ea05 --- /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 { + 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 7f8e907a..823d36c1 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 c1137954..bb6df388 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, + } + } +}