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 .
diff --git a/src/unix/bsd/apple/b32.rs b/src/unix/bsd/apple/b32.rs
index 284eae3..13b1a0b 100644
--- a/src/unix/bsd/apple/b32.rs
+++ b/src/unix/bsd/apple/b32.rs
@@ -52,32 +52,32 @@
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_attr_t {
-    fn eq(&self, other: &pthread_attr_t) -> bool {
-        self.__sig == other.__sig
-            && self.__opaque
-                .iter()
-                .zip(other.__opaque.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for pthread_attr_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for pthread_attr_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("pthread_attr_t")
-            .field("__sig", &self.__sig)
-            // FIXME: .field("__opaque", &self.__opaque)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_attr_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.__sig.hash(state);
-        self.__opaque.hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for pthread_attr_t {
+            fn eq(&self, other: &pthread_attr_t) -> bool {
+                self.__sig == other.__sig
+                    && self.__opaque
+                    .iter()
+                    .zip(other.__opaque.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for pthread_attr_t {}
+        impl ::fmt::Debug for pthread_attr_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("pthread_attr_t")
+                    .field("__sig", &self.__sig)
+                // FIXME: .field("__opaque", &self.__opaque)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for pthread_attr_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.__sig.hash(state);
+                self.__opaque.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/bsd/apple/b64.rs b/src/unix/bsd/apple/b64.rs
index 2161fc4..50b48fa 100644
--- a/src/unix/bsd/apple/b64.rs
+++ b/src/unix/bsd/apple/b64.rs
@@ -57,32 +57,32 @@
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_attr_t {
-    fn eq(&self, other: &pthread_attr_t) -> bool {
-        self.__sig == other.__sig
-            && self.__opaque
-                .iter()
-                .zip(other.__opaque.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for pthread_attr_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for pthread_attr_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("pthread_attr_t")
-            .field("__sig", &self.__sig)
-            // FIXME: .field("__opaque", &self.__opaque)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_attr_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.__sig.hash(state);
-        self.__opaque.hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for pthread_attr_t {
+            fn eq(&self, other: &pthread_attr_t) -> bool {
+                self.__sig == other.__sig
+                    && self.__opaque
+                    .iter()
+                    .zip(other.__opaque.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for pthread_attr_t {}
+        impl ::fmt::Debug for pthread_attr_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("pthread_attr_t")
+                    .field("__sig", &self.__sig)
+                // FIXME: .field("__opaque", &self.__opaque)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for pthread_attr_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.__sig.hash(state);
+                self.__opaque.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs
index 8533218..670ef56 100644
--- a/src/unix/bsd/apple/mod.rs
+++ b/src/unix/bsd/apple/mod.rs
@@ -42,6 +42,11 @@
 }
 
 s! {
+    pub struct ip_mreq {
+        pub imr_multiaddr: in_addr,
+        pub imr_interface: in_addr,
+    }
+
     pub struct aiocb {
         pub aio_fildes: ::c_int,
         pub aio_offset: ::off_t,
@@ -189,16 +194,6 @@
         pub sin_zero: [::c_char; 8],
     }
 
-    #[cfg_attr(feature = "rustc-dep-of-std", repr(packed(4)))]
-    pub struct kevent {
-        pub ident: ::uintptr_t,
-        pub filter: ::int16_t,
-        pub flags: ::uint16_t,
-        pub fflags: ::uint32_t,
-        pub data: ::intptr_t,
-        pub udata: *mut ::c_void,
-    }
-
     pub struct kevent64_s {
         pub ident: ::uint64_t,
         pub filter: ::int16_t,
@@ -473,7 +468,37 @@
         pub sem_flg: ::c_short,
     }
 
-    #[cfg_attr(feature = "rustc-dep-of-std", repr(packed(4)))]
+    // sys/shm.h
+
+    pub struct arphdr {
+        pub ar_hrd: u16,
+        pub ar_pro: u16,
+        pub ar_hln: u8,
+        pub ar_pln: u8,
+        pub ar_op: u16,
+    }
+
+    pub struct in_addr {
+        pub s_addr: ::in_addr_t,
+    }
+}
+
+s_no_extra_traits!{
+    // FIXME: https://github.com/rust-lang/libc/issues/1243
+    #[allow(missing_debug_implementations)]
+    #[cfg_attr(libc_packedN, repr(packed(4)))]
+    pub struct kevent {
+        pub ident: ::uintptr_t,
+        pub filter: ::int16_t,
+        pub flags: ::uint16_t,
+        pub fflags: ::uint32_t,
+        pub data: ::intptr_t,
+        pub udata: *mut ::c_void,
+    }
+
+    // FIXME: https://github.com/rust-lang/libc/issues/1243
+    #[allow(missing_debug_implementations)]
+    #[cfg_attr(libc_packedN, repr(packed(4)))]
     pub struct semid_ds {
         // Note the manpage shows different types than the system header.
         pub sem_perm: ipc_perm,
@@ -486,9 +511,9 @@
         pub sem_pad3: [::int32_t; 4],
     }
 
-    // sys/shm.h
-
-    #[cfg_attr(feature = "rustc-dep-of-std", repr(packed(4)))]
+    // FIXME: https://github.com/rust-lang/libc/issues/1243
+    #[allow(missing_debug_implementations)]
+    #[cfg_attr(libc_packedN, repr(packed(4)))]
     pub struct shmid_ds {
         pub shm_perm: ipc_perm,
         pub shm_segsz: ::size_t,
@@ -500,23 +525,6 @@
         pub shm_ctime: ::time_t,  // FIXME: 64-bit wrong align => wrong offset
         // FIXME: 64-bit wrong align => wrong offset:
         pub shm_internal: *mut ::c_void,
-
-    }
-
-    pub struct arphdr {
-        pub ar_hrd: u16,
-        pub ar_pro: u16,
-        pub ar_hln: u8,
-        pub ar_pln: u8,
-        pub ar_op: u16,
-    }
-}
-
-s_no_extra_traits!{
-    pub union semun {
-        pub val: ::c_int,
-        pub buf: *mut semid_ds,
-        pub array: *mut ::c_ushort,
     }
 
     pub struct proc_threadinfo {
@@ -596,377 +604,383 @@
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for semun {
-    fn eq(&self, other: &semun) -> bool {
-        unsafe { self.val == other.val }
+cfg_if! {
+    if #[cfg(libc_union)] {
+        s_no_extra_traits! {
+            pub union semun {
+                pub val: ::c_int,
+                pub buf: *mut semid_ds,
+                pub array: *mut ::c_ushort,
+            }
+        }
+
+        cfg_if! {
+            if #[cfg(feature = "extra_traits")] {
+                impl PartialEq for semun {
+                    fn eq(&self, other: &semun) -> bool {
+                        unsafe { self.val == other.val }
+                    }
+                }
+                impl Eq for semun {}
+                impl ::fmt::Debug for semun {
+                    fn fmt(&self, f: &mut ::fmt::Formatter)
+                           -> ::fmt::Result {
+                        f.debug_struct("semun")
+                            .field("val", unsafe { &self.val })
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for semun {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        unsafe { self.val.hash(state) };
+                    }
+                }
+            }
+        }
     }
 }
-#[cfg(feature = "extra_traits")]
-impl Eq for semun {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for semun {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("semun")
-            .field("val", unsafe { &self.val })
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for semun {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        unsafe { self.val.hash(state) };
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for proc_threadinfo {
-    fn eq(&self, other: &proc_threadinfo) -> bool {
-        self.pth_user_time == other.pth_user_time
-            && self.pth_system_time == other.pth_system_time
-            && self.pth_cpu_usage == other.pth_cpu_usage
-            && self.pth_policy == other.pth_policy
-            && self.pth_run_state == other.pth_run_state
-            && self.pth_flags == other.pth_flags
-            && self.pth_sleep_time == other.pth_sleep_time
-            && self.pth_curpri == other.pth_curpri
-            && self.pth_priority == other.pth_priority
-            && self.pth_maxpriority == other.pth_maxpriority
-            && self
-                .pth_name
-                .iter()
-                .zip(other.pth_name.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for proc_threadinfo {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for proc_threadinfo {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("proc_threadinfo")
-            .field("pth_user_time", &self.pth_user_time)
-            .field("pth_system_time", &self.pth_system_time)
-            .field("pth_cpu_usage", &self.pth_cpu_usage)
-            .field("pth_policy", &self.pth_policy)
-            .field("pth_run_state", &self.pth_run_state)
-            .field("pth_flags", &self.pth_flags)
-            .field("pth_sleep_time", &self.pth_sleep_time)
-            .field("pth_curpri", &self.pth_curpri)
-            .field("pth_priority", &self.pth_priority)
-            .field("pth_maxpriority", &self.pth_maxpriority)
-            // FIXME: .field("pth_name", &self.pth_name)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for proc_threadinfo {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.pth_user_time.hash(state);
-        self.pth_system_time.hash(state);
-        self.pth_cpu_usage.hash(state);
-        self.pth_policy.hash(state);
-        self.pth_run_state.hash(state);
-        self.pth_flags.hash(state);
-        self.pth_sleep_time.hash(state);
-        self.pth_curpri.hash(state);
-        self.pth_priority.hash(state);
-        self.pth_maxpriority.hash(state);
-        self.pth_name.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for statfs {
-    fn eq(&self, other: &statfs) -> bool {
-        self.f_bsize == other.f_bsize
-            && self.f_iosize == other.f_iosize
-            && self.f_blocks == other.f_blocks
-            && self.f_bfree == other.f_bfree
-            && self.f_bavail == other.f_bavail
-            && self.f_files == other.f_files
-            && self.f_ffree == other.f_ffree
-            && self.f_fsid == other.f_fsid
-            && self.f_owner == other.f_owner
-            && self.f_flags == other.f_flags
-            && self.f_fssubtype == other.f_fssubtype
-            && self.f_fstypename == other.f_fstypename
-            && self.f_type == other.f_type
-            && self
-                .f_mntonname
-                .iter()
-                .zip(other.f_mntonname.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .f_mntfromname
-                .iter()
-                .zip(other.f_mntfromname.iter())
-                .all(|(a,b)| a == b)
-            && self.f_reserved == other.f_reserved
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for statfs {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for statfs {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("statfs")
-            .field("f_bsize", &self.f_bsize)
-            .field("f_iosize", &self.f_iosize)
-            .field("f_blocks", &self.f_blocks)
-            .field("f_bfree", &self.f_bfree)
-            .field("f_bavail", &self.f_bavail)
-            .field("f_files", &self.f_files)
-            .field("f_ffree", &self.f_ffree)
-            .field("f_fsid", &self.f_fsid)
-            .field("f_owner", &self.f_owner)
-            .field("f_flags", &self.f_flags)
-            .field("f_fssubtype", &self.f_fssubtype)
-            .field("f_fstypename", &self.f_fstypename)
-            .field("f_type", &self.f_type)
-            // FIXME: .field("f_mntonname", &self.f_mntonname)
-            // FIXME: .field("f_mntfromname", &self.f_mntfromname)
-            .field("f_reserved", &self.f_reserved)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for statfs {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.f_bsize.hash(state);
-        self.f_iosize.hash(state);
-        self.f_blocks.hash(state);
-        self.f_bfree.hash(state);
-        self.f_bavail.hash(state);
-        self.f_files.hash(state);
-        self.f_ffree.hash(state);
-        self.f_fsid.hash(state);
-        self.f_owner.hash(state);
-        self.f_flags.hash(state);
-        self.f_fssubtype.hash(state);
-        self.f_fstypename.hash(state);
-        self.f_type.hash(state);
-        self.f_mntonname.hash(state);
-        self.f_mntfromname.hash(state);
-        self.f_reserved.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for dirent {
-    fn eq(&self, other: &dirent) -> bool {
-        self.d_ino == other.d_ino
-            && self.d_seekoff == other.d_seekoff
-            && self.d_reclen == other.d_reclen
-            && self.d_namlen == other.d_namlen
-            && self.d_type == other.d_type
-            && self
-                .d_name
-                .iter()
-                .zip(other.d_name.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for dirent {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for dirent {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("dirent")
-            .field("d_ino", &self.d_ino)
-            .field("d_seekoff", &self.d_seekoff)
-            .field("d_reclen", &self.d_reclen)
-            .field("d_namlen", &self.d_namlen)
-            .field("d_type", &self.d_type)
-            // FIXME: .field("d_name", &self.d_name)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for dirent {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.d_ino.hash(state);
-        self.d_seekoff.hash(state);
-        self.d_reclen.hash(state);
-        self.d_namlen.hash(state);
-        self.d_type.hash(state);
-        self.d_name.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_rwlock_t {
-    fn eq(&self, other: &pthread_rwlock_t) -> bool {
-        self.__sig == other.__sig
-            && self.
-                __opaque
-                .iter()
-                .zip(other.__opaque.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for pthread_rwlock_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for pthread_rwlock_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("pthread_rwlock_t")
-            .field("__sig", &self.__sig)
-            // FIXME: .field("__opaque", &self.__opaque)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_rwlock_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.__sig.hash(state);
-        self.__opaque.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_mutex_t {
-    fn eq(&self, other: &pthread_mutex_t) -> bool {
-        self.__sig == other.__sig
-            && self.
-                __opaque
-                .iter()
-                .zip(other.__opaque.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for pthread_mutex_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for pthread_mutex_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("pthread_mutex_t")
-            .field("__sig", &self.__sig)
-            // FIXME: .field("__opaque", &self.__opaque)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_mutex_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.__sig.hash(state);
-        self.__opaque.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_cond_t {
-    fn eq(&self, other: &pthread_cond_t) -> bool {
-        self.__sig == other.__sig
-            && self.
-                __opaque
-                .iter()
-                .zip(other.__opaque.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for pthread_cond_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for pthread_cond_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("pthread_cond_t")
-            .field("__sig", &self.__sig)
-            // FIXME: .field("__opaque", &self.__opaque)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_cond_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.__sig.hash(state);
-        self.__opaque.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for sockaddr_storage {
-    fn eq(&self, other: &sockaddr_storage) -> bool {
-        self.ss_len == other.ss_len
-            && self.ss_family == other.ss_family
-            && self
-                .__ss_pad1
-                .iter()
-                .zip(other.__ss_pad1.iter())
-                .all(|(a, b)| a == b)
-            && self.__ss_align == other.__ss_align
-            && self
-                .__ss_pad2
-                .iter()
-                .zip(other.__ss_pad2.iter())
-                .all(|(a, b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for sockaddr_storage {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for sockaddr_storage {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("sockaddr_storage")
-            .field("ss_len", &self.ss_len)
-            .field("ss_family", &self.ss_family)
-            .field("__ss_pad1", &self.__ss_pad1)
-            .field("__ss_align", &self.__ss_align)
-            // FIXME: .field("__ss_pad2", &self.__ss_pad2)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for sockaddr_storage {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.ss_len.hash(state);
-        self.ss_family.hash(state);
-        self.__ss_pad1.hash(state);
-        self.__ss_align.hash(state);
-        self.__ss_pad2.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for utmpx {
-    fn eq(&self, other: &utmpx) -> bool {
-        self.ut_user
-            .iter()
-            .zip(other.ut_user.iter())
-            .all(|(a,b)| a == b)
-            && self.ut_id == other.ut_id
-            && self.ut_line == other.ut_line
-            && self.ut_pid == other.ut_pid
-            && self.ut_type == other.ut_type
-            && self.ut_tv == other.ut_tv
-            && self
-                .ut_host
-                .iter()
-                .zip(other.ut_host.iter())
-                .all(|(a,b)| a == b)
-            && self.ut_pad == other.ut_pad
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for utmpx {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for utmpx {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("utmpx")
-            // FIXME: .field("ut_user", &self.ut_user)
-            .field("ut_id", &self.ut_id)
-            .field("ut_line", &self.ut_line)
-            .field("ut_pid", &self.ut_pid)
-            .field("ut_type", &self.ut_type)
-            .field("ut_tv", &self.ut_tv)
-            // FIXME: .field("ut_host", &self.ut_host)
-            .field("ut_pad", &self.ut_pad)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for utmpx {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.ut_user.hash(state);
-        self.ut_id.hash(state);
-        self.ut_line.hash(state);
-        self.ut_pid.hash(state);
-        self.ut_type.hash(state);
-        self.ut_tv.hash(state);
-        self.ut_host.hash(state);
-        self.ut_pad.hash(state);
+
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for proc_threadinfo {
+            fn eq(&self, other: &proc_threadinfo) -> bool {
+                self.pth_user_time == other.pth_user_time
+                    && self.pth_system_time == other.pth_system_time
+                    && self.pth_cpu_usage == other.pth_cpu_usage
+                    && self.pth_policy == other.pth_policy
+                    && self.pth_run_state == other.pth_run_state
+                    && self.pth_flags == other.pth_flags
+                    && self.pth_sleep_time == other.pth_sleep_time
+                    && self.pth_curpri == other.pth_curpri
+                    && self.pth_priority == other.pth_priority
+                    && self.pth_maxpriority == other.pth_maxpriority
+                    && self.pth_name
+                           .iter()
+                           .zip(other.pth_name.iter())
+                           .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for proc_threadinfo {}
+        impl ::fmt::Debug for proc_threadinfo {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("proc_threadinfo")
+                    .field("pth_user_time", &self.pth_user_time)
+                    .field("pth_system_time", &self.pth_system_time)
+                    .field("pth_cpu_usage", &self.pth_cpu_usage)
+                    .field("pth_policy", &self.pth_policy)
+                    .field("pth_run_state", &self.pth_run_state)
+                    .field("pth_flags", &self.pth_flags)
+                    .field("pth_sleep_time", &self.pth_sleep_time)
+                    .field("pth_curpri", &self.pth_curpri)
+                    .field("pth_priority", &self.pth_priority)
+                    .field("pth_maxpriority", &self.pth_maxpriority)
+                      // FIXME: .field("pth_name", &self.pth_name)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for proc_threadinfo {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.pth_user_time.hash(state);
+                self.pth_system_time.hash(state);
+                self.pth_cpu_usage.hash(state);
+                self.pth_policy.hash(state);
+                self.pth_run_state.hash(state);
+                self.pth_flags.hash(state);
+                self.pth_sleep_time.hash(state);
+                self.pth_curpri.hash(state);
+                self.pth_priority.hash(state);
+                self.pth_maxpriority.hash(state);
+                self.pth_name.hash(state);
+            }
+        }
+
+        impl PartialEq for statfs {
+            fn eq(&self, other: &statfs) -> bool {
+                self.f_bsize == other.f_bsize
+                    && self.f_iosize == other.f_iosize
+                    && self.f_blocks == other.f_blocks
+                    && self.f_bfree == other.f_bfree
+                    && self.f_bavail == other.f_bavail
+                    && self.f_files == other.f_files
+                    && self.f_ffree == other.f_ffree
+                    && self.f_fsid == other.f_fsid
+                    && self.f_owner == other.f_owner
+                    && self.f_flags == other.f_flags
+                    && self.f_fssubtype == other.f_fssubtype
+                    && self.f_fstypename == other.f_fstypename
+                    && self.f_type == other.f_type
+                    && self
+                    .f_mntonname
+                    .iter()
+                    .zip(other.f_mntonname.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .f_mntfromname
+                    .iter()
+                    .zip(other.f_mntfromname.iter())
+                    .all(|(a,b)| a == b)
+                    && self.f_reserved == other.f_reserved
+            }
+        }
+
+        impl Eq for statfs {}
+        impl ::fmt::Debug for statfs {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("statfs")
+                    .field("f_bsize", &self.f_bsize)
+                    .field("f_iosize", &self.f_iosize)
+                    .field("f_blocks", &self.f_blocks)
+                    .field("f_bfree", &self.f_bfree)
+                    .field("f_bavail", &self.f_bavail)
+                    .field("f_files", &self.f_files)
+                    .field("f_ffree", &self.f_ffree)
+                    .field("f_fsid", &self.f_fsid)
+                    .field("f_owner", &self.f_owner)
+                    .field("f_flags", &self.f_flags)
+                    .field("f_fssubtype", &self.f_fssubtype)
+                    .field("f_fstypename", &self.f_fstypename)
+                    .field("f_type", &self.f_type)
+                // FIXME: .field("f_mntonname", &self.f_mntonname)
+                // FIXME: .field("f_mntfromname", &self.f_mntfromname)
+                    .field("f_reserved", &self.f_reserved)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for statfs {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.f_bsize.hash(state);
+                self.f_iosize.hash(state);
+                self.f_blocks.hash(state);
+                self.f_bfree.hash(state);
+                self.f_bavail.hash(state);
+                self.f_files.hash(state);
+                self.f_ffree.hash(state);
+                self.f_fsid.hash(state);
+                self.f_owner.hash(state);
+                self.f_flags.hash(state);
+                self.f_fssubtype.hash(state);
+                self.f_fstypename.hash(state);
+                self.f_type.hash(state);
+                self.f_mntonname.hash(state);
+                self.f_mntfromname.hash(state);
+                self.f_reserved.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_seekoff == other.d_seekoff
+                    && self.d_reclen == other.d_reclen
+                    && self.d_namlen == other.d_namlen
+                    && self.d_type == other.d_type
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent {}
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_ino", &self.d_ino)
+                    .field("d_seekoff", &self.d_seekoff)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_namlen", &self.d_namlen)
+                    .field("d_type", &self.d_type)
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_ino.hash(state);
+                self.d_seekoff.hash(state);
+                self.d_reclen.hash(state);
+                self.d_namlen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+        impl PartialEq for pthread_rwlock_t {
+            fn eq(&self, other: &pthread_rwlock_t) -> bool {
+                self.__sig == other.__sig
+                    && self.
+                    __opaque
+                    .iter()
+                    .zip(other.__opaque.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for pthread_rwlock_t {}
+        impl ::fmt::Debug for pthread_rwlock_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("pthread_rwlock_t")
+                    .field("__sig", &self.__sig)
+                    // FIXME: .field("__opaque", &self.__opaque)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for pthread_rwlock_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.__sig.hash(state);
+                self.__opaque.hash(state);
+            }
+        }
+
+        impl PartialEq for pthread_mutex_t {
+            fn eq(&self, other: &pthread_mutex_t) -> bool {
+                self.__sig == other.__sig
+                    && self.
+                    __opaque
+                    .iter()
+                    .zip(other.__opaque.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for pthread_mutex_t {}
+
+        impl ::fmt::Debug for pthread_mutex_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("pthread_mutex_t")
+                    .field("__sig", &self.__sig)
+                    // FIXME: .field("__opaque", &self.__opaque)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for pthread_mutex_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.__sig.hash(state);
+                self.__opaque.hash(state);
+            }
+        }
+
+        impl PartialEq for pthread_cond_t {
+            fn eq(&self, other: &pthread_cond_t) -> bool {
+                self.__sig == other.__sig
+                    && self.
+                    __opaque
+                    .iter()
+                    .zip(other.__opaque.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for pthread_cond_t {}
+
+        impl ::fmt::Debug for pthread_cond_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("pthread_cond_t")
+                    .field("__sig", &self.__sig)
+                    // FIXME: .field("__opaque", &self.__opaque)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for pthread_cond_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.__sig.hash(state);
+                self.__opaque.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_storage {
+            fn eq(&self, other: &sockaddr_storage) -> bool {
+                self.ss_len == other.ss_len
+                    && self.ss_family == other.ss_family
+                    && self
+                    .__ss_pad1
+                    .iter()
+                    .zip(other.__ss_pad1.iter())
+                    .all(|(a, b)| a == b)
+                    && self.__ss_align == other.__ss_align
+                    && self
+                    .__ss_pad2
+                    .iter()
+                    .zip(other.__ss_pad2.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+
+        impl Eq for sockaddr_storage {}
+
+        impl ::fmt::Debug for sockaddr_storage {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_storage")
+                    .field("ss_len", &self.ss_len)
+                    .field("ss_family", &self.ss_family)
+                    .field("__ss_pad1", &self.__ss_pad1)
+                    .field("__ss_align", &self.__ss_align)
+                    // FIXME: .field("__ss_pad2", &self.__ss_pad2)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for sockaddr_storage {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ss_len.hash(state);
+                self.ss_family.hash(state);
+                self.__ss_pad1.hash(state);
+                self.__ss_align.hash(state);
+                self.__ss_pad2.hash(state);
+            }
+        }
+
+        impl PartialEq for utmpx {
+            fn eq(&self, other: &utmpx) -> bool {
+                self.ut_user
+                    .iter()
+                    .zip(other.ut_user.iter())
+                    .all(|(a,b)| a == b)
+                    && self.ut_id == other.ut_id
+                    && self.ut_line == other.ut_line
+                    && self.ut_pid == other.ut_pid
+                    && self.ut_type == other.ut_type
+                    && self.ut_tv == other.ut_tv
+                    && self
+                    .ut_host
+                    .iter()
+                    .zip(other.ut_host.iter())
+                    .all(|(a,b)| a == b)
+                    && self.ut_pad == other.ut_pad
+            }
+        }
+
+        impl Eq for utmpx {}
+
+        impl ::fmt::Debug for utmpx {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utmpx")
+                    // FIXME: .field("ut_user", &self.ut_user)
+                    .field("ut_id", &self.ut_id)
+                    .field("ut_line", &self.ut_line)
+                    .field("ut_pid", &self.ut_pid)
+                    .field("ut_type", &self.ut_type)
+                    .field("ut_tv", &self.ut_tv)
+                    // FIXME: .field("ut_host", &self.ut_host)
+                    .field("ut_pad", &self.ut_pad)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for utmpx {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ut_user.hash(state);
+                self.ut_id.hash(state);
+                self.ut_line.hash(state);
+                self.ut_pid.hash(state);
+                self.ut_type.hash(state);
+                self.ut_tv.hash(state);
+                self.ut_host.hash(state);
+                self.ut_pad.hash(state);
+            }
+        }
     }
 }
 
@@ -2765,9 +2779,18 @@
 pub const SF_APPEND:        ::c_uint = 0x00040000;
 pub const UF_HIDDEN:        ::c_uint = 0x00008000;
 
-fn __DARWIN_ALIGN32(p: usize) -> usize {
-    const __DARWIN_ALIGNBYTES32: usize = mem::size_of::<u32>() - 1;
-    p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        fn __DARWIN_ALIGN32(p: usize) -> usize {
+            const __DARWIN_ALIGNBYTES32: usize = mem::size_of::<u32>() - 1;
+            p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
+        }
+    } else {
+        fn __DARWIN_ALIGN32(p: usize) -> usize {
+            let __DARWIN_ALIGNBYTES32: usize = mem::size_of::<u32>() - 1;
+            p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
+        }
+    }
 }
 
 f! {
diff --git a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
index a780b08..dac614f 100644
--- a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
@@ -33,6 +33,14 @@
 }
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
+
 pub const MAP_32BIT: ::c_int = 0x00080000;
diff --git a/src/unix/bsd/freebsdlike/freebsd/arm.rs b/src/unix/bsd/freebsdlike/freebsd/arm.rs
index bc4da64..99a761e 100644
--- a/src/unix/bsd/freebsdlike/freebsd/arm.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/arm.rs
@@ -35,6 +35,13 @@
 }
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 4 - 1;
+    }
+}
 pub const MAP_32BIT: ::c_int = 0x00080000;
diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs
index 99f3675..0d0eb3f 100644
--- a/src/unix/bsd/freebsdlike/freebsd/mod.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs
@@ -21,17 +21,6 @@
 pub type posix_spawn_file_actions_t = *mut ::c_void;
 
 s! {
-    pub struct utmpx {
-        pub ut_type: ::c_short,
-        pub ut_tv: ::timeval,
-        pub ut_id: [::c_char; 8],
-        pub ut_pid: ::pid_t,
-        pub ut_user: [::c_char; 32],
-        pub ut_line: [::c_char; 16],
-        pub ut_host: [::c_char; 128],
-        pub __ut_spare: [::c_char; 64],
-    }
-
     pub struct aiocb {
         pub aio_fildes: ::c_int,
         pub aio_offset: ::off_t,
@@ -48,14 +37,6 @@
         pub aio_sigevent: sigevent
     }
 
-    pub struct dirent {
-        pub d_fileno: u32,
-        pub d_reclen: u16,
-        pub d_type: u8,
-        pub d_namlen: u8,
-        pub d_name: [::c_char; 256],
-    }
-
     pub struct jail {
         pub version: u32,
         pub path: *mut ::c_char,
@@ -101,31 +82,6 @@
         pub f_namemax: ::c_ulong,
     }
 
-    pub struct statfs {
-        pub f_version: ::uint32_t,
-        pub f_type: ::uint32_t,
-        pub f_flags: ::uint64_t,
-        pub f_bsize: ::uint64_t,
-        pub f_iosize: ::uint64_t,
-        pub f_blocks: ::uint64_t,
-        pub f_bfree: ::uint64_t,
-        pub f_bavail: ::int64_t,
-        pub f_files: ::uint64_t,
-        pub f_ffree: ::int64_t,
-        pub f_syncwrites: ::uint64_t,
-        pub f_asyncwrites: ::uint64_t,
-        pub f_syncreads: ::uint64_t,
-        pub f_asyncreads: ::uint64_t,
-        f_spare: [::uint64_t; 10],
-        pub f_namemax: ::uint32_t,
-        pub f_owner: ::uid_t,
-        pub f_fsid: ::fsid_t,
-        f_charspare: [::c_char; 80],
-        pub f_fstypename: [::c_char; 16],
-        pub f_mntfromname: [::c_char; 88],
-        pub f_mntonname: [::c_char; 88],
-    }
-
     // internal structure has changed over time
     pub struct _sem {
         data: [u32; 4],
@@ -174,6 +130,62 @@
         __cr_unused1: *mut ::c_void,
     }
 
+    pub struct stack_t {
+        pub ss_sp: *mut ::c_void,
+        pub ss_size: ::size_t,
+        pub ss_flags: ::c_int,
+    }
+}
+
+s_no_extra_traits! {
+    #[allow(missing_debug_implementations)]
+    pub struct utmpx {
+        pub ut_type: ::c_short,
+        pub ut_tv: ::timeval,
+        pub ut_id: [::c_char; 8],
+        pub ut_pid: ::pid_t,
+        pub ut_user: [::c_char; 32],
+        pub ut_line: [::c_char; 16],
+        pub ut_host: [::c_char; 128],
+        pub __ut_spare: [::c_char; 64],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct dirent {
+        pub d_fileno: u32,
+        pub d_reclen: u16,
+        pub d_type: u8,
+        pub d_namlen: u8,
+        pub d_name: [::c_char; 256],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct statfs {
+        pub f_version: ::uint32_t,
+        pub f_type: ::uint32_t,
+        pub f_flags: ::uint64_t,
+        pub f_bsize: ::uint64_t,
+        pub f_iosize: ::uint64_t,
+        pub f_blocks: ::uint64_t,
+        pub f_bfree: ::uint64_t,
+        pub f_bavail: ::int64_t,
+        pub f_files: ::uint64_t,
+        pub f_ffree: ::int64_t,
+        pub f_syncwrites: ::uint64_t,
+        pub f_asyncwrites: ::uint64_t,
+        pub f_syncreads: ::uint64_t,
+        pub f_asyncreads: ::uint64_t,
+        f_spare: [::uint64_t; 10],
+        pub f_namemax: ::uint32_t,
+        pub f_owner: ::uid_t,
+        pub f_fsid: ::fsid_t,
+        f_charspare: [::c_char; 80],
+        pub f_fstypename: [::c_char; 16],
+        pub f_mntfromname: [::c_char; 88],
+        pub f_mntonname: [::c_char; 88],
+    }
+
+    #[allow(missing_debug_implementations)]
     pub struct sockaddr_dl {
         pub sdl_len: ::c_uchar,
         pub sdl_family: ::c_uchar,
@@ -184,12 +196,6 @@
         pub sdl_slen: ::c_uchar,
         pub sdl_data: [::c_char; 46],
     }
-
-    pub struct stack_t {
-        pub ss_sp: *mut ::c_void,
-        pub ss_size: ::size_t,
-        pub ss_flags: ::c_int,
-    }
 }
 
 pub const SIGEV_THREAD_ID: ::c_int = 4;
diff --git a/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs b/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs
index c06e1ae..517f296 100644
--- a/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs
@@ -31,6 +31,14 @@
 }
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
+
 pub const MAP_32BIT: ::c_int = 0x00080000;
diff --git a/src/unix/bsd/freebsdlike/freebsd/x86.rs b/src/unix/bsd/freebsdlike/freebsd/x86.rs
index 2eaeec7..b31e335 100644
--- a/src/unix/bsd/freebsdlike/freebsd/x86.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/x86.rs
@@ -34,5 +34,12 @@
 }
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
diff --git a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
index e9dcf78..89819fd 100644
--- a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
@@ -33,6 +33,13 @@
 }
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
 pub const MAP_32BIT: ::c_int = 0x00080000;
diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs
index 73f8852..ca9ed98 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -23,6 +23,15 @@
 }
 
 s! {
+    pub struct in_addr {
+        pub s_addr: ::in_addr_t,
+    }
+
+    pub struct ip_mreq {
+        pub imr_multiaddr: in_addr,
+        pub imr_interface: in_addr,
+    }
+
     pub struct glob_t {
         pub gl_pathc:  ::size_t,
         pub gl_matchc: ::size_t,
@@ -46,14 +55,6 @@
         pub udata: *mut ::c_void,
     }
 
-    pub struct sockaddr_storage {
-        pub ss_len: u8,
-        pub ss_family: ::sa_family_t,
-        __ss_pad1: [u8; 6],
-        __ss_align: i64,
-        __ss_pad2: [u8; 112],
-    }
-
     pub struct addrinfo {
         pub ai_flags: ::c_int,
         pub ai_family: ::c_int,
@@ -187,6 +188,17 @@
     }
 }
 
+s_no_extra_traits! {
+    #[allow(missing_debug_implementations)]
+    pub struct sockaddr_storage {
+        pub ss_len: u8,
+        pub ss_family: ::sa_family_t,
+        __ss_pad1: [u8; 6],
+        __ss_align: i64,
+        __ss_pad2: [u8; 112],
+    }
+}
+
 pub const AIO_LISTIO_MAX: ::c_int = 16;
 pub const AIO_CANCELED: ::c_int = 1;
 pub const AIO_NOTCANCELED: ::c_int = 2;
diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs
index 0541c5a..8b5ec8c 100644
--- a/src/unix/bsd/mod.rs
+++ b/src/unix/bsd/mod.rs
@@ -137,89 +137,92 @@
 
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for sockaddr_un {
-    fn eq(&self, other: &sockaddr_un) -> bool {
-        self.sun_len == other.sun_len
-            && self.sun_family == other.sun_family
-            && self
-                .sun_path
-                .iter()
-                .zip(other.sun_path.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for sockaddr_un {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for sockaddr_un {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("sockaddr_un")
-            .field("sun_len", &self.sun_len)
-            .field("sun_family", &self.sun_family)
-            // FIXME: .field("sun_path", &self.sun_path)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for sockaddr_un {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.sun_len.hash(state);
-        self.sun_family.hash(state);
-        self.sun_path.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for utsname {
-    fn eq(&self, other: &utsname) -> bool {
-        self.sysname
-            .iter()
-            .zip(other.sysname.iter())
-            .all(|(a,b)| a == b)
-            && self
-                .nodename
-                .iter()
-                .zip(other.nodename.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .release
-                .iter()
-                .zip(other.release.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .version
-                .iter()
-                .zip(other.version.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .machine
-                .iter()
-                .zip(other.machine.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for utsname {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for utsname {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("utsname")
-            // FIXME: .field("sysname", &self.sysname)
-            // FIXME: .field("nodename", &self.nodename)
-            // FIXME: .field("release", &self.release)
-            // FIXME: .field("version", &self.version)
-            // FIXME: .field("machine", &self.machine)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for utsname {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.sysname.hash(state);
-        self.nodename.hash(state);
-        self.release.hash(state);
-        self.version.hash(state);
-        self.machine.hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for sockaddr_un {
+            fn eq(&self, other: &sockaddr_un) -> bool {
+                self.sun_len == other.sun_len
+                    && self.sun_family == other.sun_family
+                    && self
+                    .sun_path
+                    .iter()
+                    .zip(other.sun_path.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for sockaddr_un {}
+
+        impl ::fmt::Debug for sockaddr_un {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_un")
+                    .field("sun_len", &self.sun_len)
+                    .field("sun_family", &self.sun_family)
+                // FIXME: .field("sun_path", &self.sun_path)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for sockaddr_un {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sun_len.hash(state);
+                self.sun_family.hash(state);
+                self.sun_path.hash(state);
+            }
+        }
+
+        impl PartialEq for utsname {
+            fn eq(&self, other: &utsname) -> bool {
+                self.sysname
+                    .iter()
+                    .zip(other.sysname.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .nodename
+                    .iter()
+                    .zip(other.nodename.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .release
+                    .iter()
+                    .zip(other.release.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .version
+                    .iter()
+                    .zip(other.version.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .machine
+                    .iter()
+                    .zip(other.machine.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for utsname {}
+
+        impl ::fmt::Debug for utsname {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utsname")
+                // FIXME: .field("sysname", &self.sysname)
+                // FIXME: .field("nodename", &self.nodename)
+                // FIXME: .field("release", &self.release)
+                // FIXME: .field("version", &self.version)
+                // FIXME: .field("machine", &self.machine)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for utsname {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sysname.hash(state);
+                self.nodename.hash(state);
+                self.release.hash(state);
+                self.version.hash(state);
+                self.machine.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/bsd/netbsdlike/mod.rs b/src/unix/bsd/netbsdlike/mod.rs
index 764174d..d035296 100644
--- a/src/unix/bsd/netbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/mod.rs
@@ -39,14 +39,6 @@
         pub ss_flags: ::c_int,
     }
 
-    pub struct sockaddr_in {
-        pub sin_len: u8,
-        pub sin_family: ::sa_family_t,
-        pub sin_port: ::in_port_t,
-        pub sin_addr: ::in_addr,
-        pub sin_zero: [::int8_t; 8],
-    }
-
     pub struct in6_pktinfo {
         pub ipi6_addr: ::in6_addr,
         pub ipi6_ifindex: ::c_uint,
diff --git a/src/unix/bsd/netbsdlike/netbsd/aarch64.rs b/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
index cda75bc..e30d731 100644
--- a/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
@@ -8,8 +8,15 @@
 pub type __cpu_simple_lock_nv_t = ::c_uchar;
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 4 - 1;
+    }
+}
 
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 0;
 pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 1;
diff --git a/src/unix/bsd/netbsdlike/netbsd/arm.rs b/src/unix/bsd/netbsdlike/netbsd/arm.rs
index 71c2cb7..cfcc139 100644
--- a/src/unix/bsd/netbsdlike/netbsd/arm.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/arm.rs
@@ -8,8 +8,15 @@
 pub type __cpu_simple_lock_nv_t = ::c_int;
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
 
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
 pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2;
diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs
index d3acfb9..36a5366 100644
--- a/src/unix/bsd/netbsdlike/netbsd/mod.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs
@@ -24,14 +24,6 @@
         _retval: ::ssize_t
     }
 
-    pub struct dirent {
-        pub d_fileno: ::ino_t,
-        pub d_reclen: u16,
-        pub d_namlen: u16,
-        pub d_type: u8,
-        pub d_name: [::c_char; 512],
-    }
-
     pub struct glob_t {
         pub gl_pathc:   ::size_t,
         pub gl_matchc:  ::size_t,
@@ -91,41 +83,7 @@
         pub st_spare: [::uint32_t; 2],
     }
 
-    pub struct statvfs {
-        pub f_flag: ::c_ulong,
-        pub f_bsize: ::c_ulong,
-        pub f_frsize: ::c_ulong,
-        pub f_iosize: ::c_ulong,
-
-        pub f_blocks: ::fsblkcnt_t,
-        pub f_bfree: ::fsblkcnt_t,
-        pub f_bavail: ::fsblkcnt_t,
-        pub f_bresvd: ::fsblkcnt_t,
-
-        pub f_files: ::fsfilcnt_t,
-        pub f_ffree: ::fsfilcnt_t,
-        pub f_favail: ::fsfilcnt_t,
-        pub f_fresvd: ::fsfilcnt_t,
-
-        pub f_syncreads: ::uint64_t,
-        pub f_syncwrites: ::uint64_t,
-
-        pub f_asyncreads: ::uint64_t,
-        pub f_asyncwrites: ::uint64_t,
-
-        pub f_fsidx: ::fsid_t,
-        pub f_fsid: ::c_ulong,
-        pub f_namemax: ::c_ulong,
-        pub f_owner: ::uid_t,
-
-        pub f_spare: [::uint32_t; 4],
-
-        pub f_fstypename: [::c_char; 32],
-        pub f_mntonname: [::c_char; 1024],
-        pub f_mntfromname: [::c_char; 1024],
-    }
-
-    pub struct addrinfo {
+     pub struct addrinfo {
         pub ai_flags: ::c_int,
         pub ai_family: ::c_int,
         pub ai_socktype: ::c_int,
@@ -136,14 +94,6 @@
         pub ai_next: *mut ::addrinfo,
     }
 
-    pub struct sockaddr_storage {
-        pub ss_len: u8,
-        pub ss_family: ::sa_family_t,
-        __ss_pad1: [u8; 6],
-        __ss_pad2: i64,
-        __ss_pad3: [u8; 112],
-    }
-
     pub struct siginfo_t {
         pub si_signo: ::c_int,
         pub si_code: ::c_int,
@@ -318,13 +268,17 @@
         pub sdl_slen: ::uint8_t,
         pub sdl_data: [::c_char; 12],
     }
+}
 
+s_no_extra_traits! {
+    #[allow(missing_debug_implementations)]
     pub struct in_pktinfo {
         pub ipi_addr: ::in_addr,
         pub ipi_ifindex: ::c_uint,
     }
 
     #[repr(packed)]
+    #[allow(missing_debug_implementations)]
     pub struct arphdr {
         pub ar_hrd: u16,
         pub ar_pro: u16,
@@ -332,6 +286,80 @@
         pub ar_pln: u8,
         pub ar_op: u16,
     }
+
+    #[repr(packed)]
+    #[allow(missing_debug_implementations)]
+    pub struct in_addr {
+        pub s_addr: ::in_addr_t,
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct ip_mreq {
+        pub imr_multiaddr: in_addr,
+        pub imr_interface: in_addr,
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct sockaddr_in {
+        pub sin_len: u8,
+        pub sin_family: ::sa_family_t,
+        pub sin_port: ::in_port_t,
+        pub sin_addr: ::in_addr,
+        pub sin_zero: [::int8_t; 8],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct dirent {
+        pub d_fileno: ::ino_t,
+        pub d_reclen: u16,
+        pub d_namlen: u16,
+        pub d_type: u8,
+        pub d_name: [::c_char; 512],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct statvfs {
+        pub f_flag: ::c_ulong,
+        pub f_bsize: ::c_ulong,
+        pub f_frsize: ::c_ulong,
+        pub f_iosize: ::c_ulong,
+
+        pub f_blocks: ::fsblkcnt_t,
+        pub f_bfree: ::fsblkcnt_t,
+        pub f_bavail: ::fsblkcnt_t,
+        pub f_bresvd: ::fsblkcnt_t,
+
+        pub f_files: ::fsfilcnt_t,
+        pub f_ffree: ::fsfilcnt_t,
+        pub f_favail: ::fsfilcnt_t,
+        pub f_fresvd: ::fsfilcnt_t,
+
+        pub f_syncreads: ::uint64_t,
+        pub f_syncwrites: ::uint64_t,
+
+        pub f_asyncreads: ::uint64_t,
+        pub f_asyncwrites: ::uint64_t,
+
+        pub f_fsidx: ::fsid_t,
+        pub f_fsid: ::c_ulong,
+        pub f_namemax: ::c_ulong,
+        pub f_owner: ::uid_t,
+
+        pub f_spare: [::uint32_t; 4],
+
+        pub f_fstypename: [::c_char; 32],
+        pub f_mntonname: [::c_char; 1024],
+        pub f_mntfromname: [::c_char; 1024],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct sockaddr_storage {
+        pub ss_len: u8,
+        pub ss_family: ::sa_family_t,
+        __ss_pad1: [u8; 6],
+        __ss_pad2: i64,
+        __ss_pad3: [u8; 112],
+    }
 }
 
 pub const AT_FDCWD: ::c_int = -100;
@@ -708,21 +736,32 @@
 
 pub const ST_NOSUID: ::c_ulong = 8;
 
-pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
-    ptm_magic: 0x33330003,
-    ptm_errorcheck: 0,
-    #[cfg(any(target_arch = "sparc", target_arch = "sparc64",
-              target_arch = "x86", target_arch = "x86_64"))]
-    ptm_pad1: [0; 3],
-    ptm_unused: 0,
-    #[cfg(any(target_arch = "sparc", target_arch = "sparc64",
-              target_arch = "x86", target_arch = "x86_64"))]
-    ptm_pad2: [0; 3],
-    ptm_waiters: 0 as *mut _,
-    ptm_owner: 0,
-    ptm_recursed: 0,
-    ptm_spare2: 0 as *mut _,
-};
+cfg_if! {
+    if #[cfg(any(target_arch = "sparc", target_arch = "sparc64",
+                 target_arch = "x86", target_arch = "x86_64"))] {
+        pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
+            ptm_magic: 0x33330003,
+            ptm_errorcheck: 0,
+            ptm_pad1: [0; 3],
+            ptm_unused: 0,
+            ptm_pad2: [0; 3],
+            ptm_waiters: 0 as *mut _,
+            ptm_owner: 0,
+            ptm_recursed: 0,
+            ptm_spare2: 0 as *mut _,
+        };
+    } else {
+        pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
+            ptm_magic: 0x33330003,
+            ptm_errorcheck: 0,
+            ptm_unused: 0,
+            ptm_waiters: 0 as *mut _,
+            ptm_owner: 0,
+            ptm_recursed: 0,
+            ptm_spare2: 0 as *mut _,
+        };
+    }
+}
 
 pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
     ptc_magic: 0x55550005,
diff --git a/src/unix/bsd/netbsdlike/netbsd/powerpc.rs b/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
index 3c682c3..10cdc73 100644
--- a/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
@@ -8,8 +8,15 @@
 pub type __cpu_simple_lock_nv_t = ::c_int;
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_double>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_double>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
 
 pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0;
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
diff --git a/src/unix/bsd/netbsdlike/netbsd/x86.rs b/src/unix/bsd/netbsdlike/netbsd/x86.rs
index 4da9968..895e7f8 100644
--- a/src/unix/bsd/netbsdlike/netbsd/x86.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/x86.rs
@@ -6,5 +6,12 @@
 pub type __cpu_simple_lock_nv_t = ::c_uchar;
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 4 - 1;
+    }
+}
diff --git a/src/unix/bsd/netbsdlike/netbsd/x86_64.rs b/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
index af1b8f8..e71a82c 100644
--- a/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
@@ -8,8 +8,15 @@
 pub type __cpu_simple_lock_nv_t = ::c_uchar;
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
 
 pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0;
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/mod.rs b/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
index 1c2e47d..0d71fde 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
@@ -17,6 +17,23 @@
 pub type caddr_t = *mut ::c_char;
 
 s! {
+    pub struct ip_mreq {
+        pub imr_multiaddr: in_addr,
+        pub imr_interface: in_addr,
+    }
+
+    pub struct in_addr {
+        pub s_addr: ::in_addr_t,
+    }
+
+    pub struct sockaddr_in {
+        pub sin_len: u8,
+        pub sin_family: ::sa_family_t,
+        pub sin_port: ::in_port_t,
+        pub sin_addr: ::in_addr,
+        pub sin_zero: [::int8_t; 8],
+    }
+
     pub struct dirent {
         pub d_fileno: ::ino_t,
         pub d_off: ::off_t,
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
index 2a28c2a..268e5af 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
@@ -5,5 +5,12 @@
 pub type c_char = u8;
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs
index a2a7a30..9bf2db8 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs
@@ -26,42 +26,6 @@
         pub int_n_sign_posn: ::c_char,
     }
 
-    pub struct statfs {
-        pub f_flags: ::uint32_t,
-        pub f_bsize: ::uint32_t,
-        pub f_iosize: ::uint32_t,
-        pub f_blocks: ::uint64_t,
-        pub f_bfree: ::uint64_t,
-        pub f_bavail: ::int64_t,
-        pub f_files: ::uint64_t,
-        pub f_ffree: ::uint64_t,
-        pub f_favail: ::int64_t,
-        pub f_syncwrites: ::uint64_t,
-        pub f_syncreads: ::uint64_t,
-        pub f_asyncwrites: ::uint64_t,
-        pub f_asyncreads: ::uint64_t,
-        pub f_fsid: ::fsid_t,
-        pub f_namemax: ::uint32_t,
-        pub f_owner: ::uid_t,
-        pub f_ctime: ::uint64_t,
-        pub f_fstypename: [::c_char; 16],
-        pub f_mntonname: [::c_char; 90],
-        pub f_mntfromname: [::c_char; 90],
-        pub f_mntfromspec: [::c_char; 90],
-        pub mount_info: mount_info,
-    }
-
-    pub union mount_info {
-        pub ufs_args: ufs_args,
-        pub mfs_args: mfs_args,
-        pub nfs_args: nfs_args,
-        pub iso_args: iso_args,
-        pub msdosfs_args: msdosfs_args,
-        pub ntfs_args: ntfs_args,
-        pub tmpfs_args: tmpfs_args,
-        align: [::c_char; 160],
-    }
-
     pub struct ufs_args {
         pub fspec: *mut ::c_char,
         pub export_info: export_args,
@@ -165,6 +129,51 @@
     }
 }
 
+s_no_extra_traits! {
+    pub union mount_info {
+        pub ufs_args: ufs_args,
+        pub mfs_args: mfs_args,
+        pub nfs_args: nfs_args,
+        pub iso_args: iso_args,
+        pub msdosfs_args: msdosfs_args,
+        pub ntfs_args: ntfs_args,
+        pub tmpfs_args: tmpfs_args,
+        align: [::c_char; 160],
+    }
+}
+
+cfg_if! {
+    if #[cfg(libc_union)] {
+        s_no_extra_traits! {
+            // This type uses the union mount_info:
+            pub struct statfs {
+                pub f_flags: ::uint32_t,
+                pub f_bsize: ::uint32_t,
+                pub f_iosize: ::uint32_t,
+                pub f_blocks: ::uint64_t,
+                pub f_bfree: ::uint64_t,
+                pub f_bavail: ::int64_t,
+                pub f_files: ::uint64_t,
+                pub f_ffree: ::uint64_t,
+                pub f_favail: ::int64_t,
+                pub f_syncwrites: ::uint64_t,
+                pub f_syncreads: ::uint64_t,
+                pub f_asyncwrites: ::uint64_t,
+                pub f_asyncreads: ::uint64_t,
+                pub f_fsid: ::fsid_t,
+                pub f_namemax: ::uint32_t,
+                pub f_owner: ::uid_t,
+                pub f_ctime: ::uint64_t,
+                pub f_fstypename: [::c_char; 16],
+                pub f_mntonname: [::c_char; 90],
+                pub f_mntfromname: [::c_char; 90],
+                pub f_mntfromspec: [::c_char; 90],
+                pub mount_info: mount_info,
+            }
+        }
+    }
+}
+
 //https://github.com/openbsd/src/blob/master/sys/sys/mount.h
 pub const ISOFSMNT_NORRIP: ::c_int = 0x1; // disable Rock Ridge Ext
 pub const ISOFSMNT_GENS: ::c_int = 0x2; // enable generation numbers
@@ -260,14 +269,20 @@
     pub fn strtonum(nptr: *const ::c_char, minval: ::c_longlong,
                     maxval: ::c_longlong,
                     errstr: *mut *const ::c_char) -> ::c_longlong;
-
-    pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int;
-    pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int;
-
     pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int;
 }
 
 cfg_if! {
+    if #[cfg(libc_union)] {
+        extern {
+            // these functions use statfs which uses the union mount_info:
+            pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int;
+            pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int;
+        }
+    }
+}
+
+cfg_if! {
     if #[cfg(target_arch = "x86")] {
         mod x86;
         pub use self::x86::*;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
index b63b69f..959c87b 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
@@ -5,5 +5,12 @@
 pub type c_char = i8;
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 4 - 1;
+    }
+}
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
index 581096f..b2025a8 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
@@ -7,8 +7,15 @@
 pub type c_char = i8;
 
 // should be pub(crate), but that requires Rust 1.18.0
-#[doc(hidden)]
-pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+cfg_if! {
+    if #[cfg(libc_const_size_of)] {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+    } else {
+        #[doc(hidden)]
+        pub const _ALIGNBYTES: usize = 8 - 1;
+    }
+}
 
 pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0;
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;