diff --git a/Cargo.toml b/Cargo.toml
index d20fc69ba86dfb6bc142bce3f4e5dfbec65c5b8e..d72aa8c97dfcde4857e972d5808d7c046e857398 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,7 +27,7 @@ default = ["use_std"]
 use_std = []
 align = []
 rustc-dep-of-std = ['align', 'rustc-std-workspace-core']
-extra_traits = ["align"]
+extra_traits = []
 
 [workspace]
 members = ["libc-test"]
diff --git a/build.rs b/build.rs
index 1852ed27903bd3db18001a25a7e5ae53f1849a6c..9b13376779f65a459b8d58e3f11d4745b5945b66 100644
--- a/build.rs
+++ b/build.rs
@@ -3,12 +3,42 @@ 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") >= 30 {
-        println!("cargo:rustc-cfg=core_cvoid");
+    let rustc_minor_ver =
+        rustc_minor_version().expect("Failed to get rustc version");
+    let rustc_dep_of_std =
+        std::env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok();
+    let align_cargo_feature = std::env::var("CARGO_FEATURE_ALIGN").is_ok();
+
+    // Rust >= 1.15 supports private module use:
+    if rustc_minor_ver >= 15 || rustc_dep_of_std {
+        println!("cargo:rustc-cfg=libc_priv_mod_use");
+    }
+
+    // Rust >= 1.19 supports unions:
+    if rustc_minor_ver >= 19 || rustc_dep_of_std {
+        println!("cargo:rustc-cfg=libc_union");
+    }
+
+    // Rust >= 1.24 supports const mem::size_of:
+    if rustc_minor_ver >= 24 || rustc_dep_of_std {
+        println!("cargo:rustc-cfg=libc_const_size_of");
+    }
+
+    // Rust >= 1.25 supports repr(align):
+    if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature {
+        println!("cargo:rustc-cfg=libc_align");
+    }
+
+    // Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it.
+    // Otherwise, it defines an incompatible type to retaining
+    // backwards-compatibility.
+    if rustc_minor_ver >= 30 || rustc_dep_of_std {
+        println!("cargo:rustc-cfg=libc_core_cvoid");
+    }
+
+    // Rust >= 1.33 supports repr(packed(N))
+    if rustc_minor_ver >= 33 || rustc_dep_of_std {
+        println!("cargo:rustc-cfg=libc_packedN");
     }
 }
 
diff --git a/src/cloudabi/mod.rs b/src/cloudabi/mod.rs
index 51859cb40b1279be564862a7d017c8146ad5368c..e5027b935b1c9de5fc4bca6961adbb2899771985 100644
--- a/src/cloudabi/mod.rs
+++ b/src/cloudabi/mod.rs
@@ -316,14 +316,15 @@ cfg_if! {
 }
 
 cfg_if! {
-    if #[cfg(core_cvoid)] {
-        pub use core::ffi::c_void;
+    if #[cfg(libc_core_cvoid)] {
+        pub use ::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)]
         #[allow(missing_copy_implementations)]
+        #[allow(missing_debug_implementations)]
         pub enum c_void {
             // Two dummy variants so the #[repr] attribute can be used.
             #[doc(hidden)]
diff --git a/src/fuchsia/align.rs b/src/fuchsia/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8d4040d003df2139e6459d6ce91d715338f7f599
--- /dev/null
+++ b/src/fuchsia/align.rs
@@ -0,0 +1,75 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            #[cfg_attr(
+                any(
+                    target_pointer_width = "32",
+                    target_arch = "x86_64"
+                ),
+                repr(align(4)))]
+            #[cfg_attr(
+                not(any(
+                    target_pointer_width = "32",
+                    target_arch = "x86_64"
+                )),
+                repr(align(8)))]
+            pub struct pthread_mutexattr_t {
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            #[cfg_attr(target_pointer_width = "32",
+                       repr(align(4)))]
+            #[cfg_attr(target_pointer_width = "64",
+                       repr(align(8)))]
+            pub struct pthread_rwlockattr_t {
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_condattr_t {
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+
+        s_no_extra_traits! {
+            #[allow(missing_debug_implementations)]
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "arm",
+                               target_arch = "x86_64")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "arm",
+                                   target_arch = "x86_64"))),
+                       repr(align(8)))]
+            pub struct pthread_mutex_t {
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            #[allow(missing_debug_implementations)]
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "arm",
+                               target_arch = "x86_64")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "arm",
+                                   target_arch = "x86_64"))),
+                       repr(align(8)))]
+            pub struct pthread_rwlock_t {
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+
+            #[allow(missing_debug_implementations)]
+            #[cfg_attr(target_pointer_width = "32",
+                       repr(align(4)))]
+            #[cfg_attr(target_pointer_width = "64",
+                       repr(align(8)))]
+            #[cfg_attr(target_arch = "x86",
+                       repr(align(4)))]
+            #[cfg_attr(not(target_arch = "x86"),
+                       repr(align(8)))]
+            pub struct pthread_cond_t {
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+        }
+    }
+}
diff --git a/src/fuchsia/mod.rs b/src/fuchsia/mod.rs
index ba20979a748a3bb41d974c9c4fbc251ae2f5e82d..6f45cc19176ef9f8675ea0ddf2a3c6905c1781c7 100644
--- a/src/fuchsia/mod.rs
+++ b/src/fuchsia/mod.rs
@@ -202,9 +202,6 @@ s! {
         pub ru_nivcsw: c_long,
         #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
         __pad14: u32,
-
-        #[cfg(any(target_env = "musl", target_os = "emscripten"))]
-        __reserved: [c_long; 16],
     }
 
     pub struct in_addr {
@@ -334,23 +331,6 @@ s! {
         pub l_pid: ::pid_t,
     }
 
-    pub struct sysinfo {
-        pub uptime: ::c_ulong,
-        pub loads: [::c_ulong; 3],
-        pub totalram: ::c_ulong,
-        pub freeram: ::c_ulong,
-        pub sharedram: ::c_ulong,
-        pub bufferram: ::c_ulong,
-        pub totalswap: ::c_ulong,
-        pub freeswap: ::c_ulong,
-        pub procs: ::c_ushort,
-        pub pad: ::c_ushort,
-        pub totalhigh: ::c_ulong,
-        pub freehigh: ::c_ulong,
-        pub mem_unit: ::c_uint,
-        pub __reserved: [::c_char; 256],
-    }
-
     pub struct ucred {
         pub pid: ::pid_t,
         pub uid: ::uid_t,
@@ -377,17 +357,6 @@ s! {
         pub sin6_scope_id: u32,
     }
 
-    pub struct sockaddr_un {
-        pub sun_family: sa_family_t,
-        pub sun_path: [::c_char; 108]
-    }
-
-    pub struct sockaddr_storage {
-        pub ss_family: sa_family_t,
-        __ss_align: ::size_t,
-        __ss_pad2: [u8; 128 - 2 * 8],
-    }
-
     pub struct addrinfo {
         pub ai_flags: ::c_int,
         pub ai_family: ::c_int,
@@ -457,15 +426,6 @@ s! {
         pub u64: ::uint64_t,
     }
 
-    pub struct utsname {
-        pub sysname: [::c_char; 65],
-        pub nodename: [::c_char; 65],
-        pub release: [::c_char; 65],
-        pub version: [::c_char; 65],
-        pub machine: [::c_char; 65],
-        pub domainname: [::c_char; 65]
-    }
-
     pub struct lconv {
         pub decimal_point: *mut ::c_char,
         pub thousands_sep: *mut ::c_char,
@@ -502,22 +462,6 @@ s! {
         pub __pad: [::c_char; 56 - 3 * 8 /* 8 == sizeof(long) */],
     }
 
-    pub struct dirent {
-        pub d_ino: ::ino_t,
-        pub d_off: ::off_t,
-        pub d_reclen: ::c_ushort,
-        pub d_type: ::c_uchar,
-        pub d_name: [::c_char; 256],
-    }
-
-    pub struct dirent64 {
-        pub d_ino: ::ino64_t,
-        pub d_off: ::off64_t,
-        pub d_reclen: ::c_ushort,
-        pub d_type: ::c_uchar,
-        pub d_name: [::c_char; 256],
-    }
-
     pub struct rlimit64 {
         pub rlim_cur: rlim64_t,
         pub rlim_max: rlim64_t,
@@ -546,122 +490,6 @@ s! {
         pub ifa_data: *mut ::c_void
     }
 
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "arm",
-                       target_arch = "x86_64")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "arm",
-                               target_arch = "x86_64")))),
-               repr(align(8)))]
-    pub struct pthread_mutex_t {
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "arm",
-                      all(target_arch = "x86_64",
-                          target_pointer_width = "32"))))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "arm",
-                      all(target_arch = "x86_64",
-                          target_pointer_width = "32"))))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "arm",
-                       target_arch = "x86_64")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "arm",
-                               target_arch = "x86_64")))),
-               repr(align(8)))]
-    pub struct pthread_rwlock_t {
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "arm",
-                      all(target_arch = "x86_64",
-                          target_pointer_width = "32"))))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "arm",
-                      all(target_arch = "x86_64",
-                          target_pointer_width = "32"))))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCK_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "32",
-                       target_arch = "x86_64",
-                       all(target_arch = "aarch64", target_env = "musl"))),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(any(target_pointer_width = "32",
-                           target_arch = "x86_64",
-                           all(target_arch = "aarch64", target_env = "musl")))),
-               repr(align(8)))]
-    pub struct pthread_mutexattr_t {
-        #[cfg(all(not(features = "align"),
-                  any(target_arch = "x86_64",
-                      all(target_arch = "aarch64", target_env = "musl"))))]
-        __align: [::c_int; 0],
-        #[cfg(all(not(features = "align"),
-                  not(any(target_arch = "x86_64",
-                          all(target_arch = "aarch64", target_env = "musl")))))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   any(target_env = "musl", target_pointer_width = "32")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(target_env = "musl"),
-                   target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct pthread_rwlockattr_t {
-        #[cfg(all(not(feature = "align"), target_env = "musl"))]
-        __align: [::c_int; 0],
-        #[cfg(all(not(feature = "align"), not(target_env = "musl")))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   target_env = "musl",
-                   target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   target_env = "musl",
-                   target_pointer_width = "64"),
-               repr(align(8)))]
-    #[cfg_attr(all(feature = "align",
-                   not(target_env = "musl"),
-                   target_arch = "x86"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(target_env = "musl"),
-                   not(target_arch = "x86")),
-               repr(align(8)))]
-    pub struct pthread_cond_t {
-        #[cfg(all(not(feature = "align"), target_env = "musl"))]
-        __align: [*const ::c_void; 0],
-        #[cfg(not(any(feature = "align", target_env = "musl")))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_COND_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_condattr_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_int; 0],
-        size: [u8; __SIZEOF_PTHREAD_CONDATTR_T],
-    }
-
     pub struct passwd {
         pub pw_name: *mut ::c_char,
         pub pw_passwd: *mut ::c_char,
@@ -1095,6 +923,67 @@ s! {
     }
 }
 
+s_no_extra_traits! {
+    #[allow(missing_debug_implementations)]
+    pub struct sysinfo {
+        pub uptime: ::c_ulong,
+        pub loads: [::c_ulong; 3],
+        pub totalram: ::c_ulong,
+        pub freeram: ::c_ulong,
+        pub sharedram: ::c_ulong,
+        pub bufferram: ::c_ulong,
+        pub totalswap: ::c_ulong,
+        pub freeswap: ::c_ulong,
+        pub procs: ::c_ushort,
+        pub pad: ::c_ushort,
+        pub totalhigh: ::c_ulong,
+        pub freehigh: ::c_ulong,
+        pub mem_unit: ::c_uint,
+        pub __reserved: [::c_char; 256],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct sockaddr_un {
+        pub sun_family: sa_family_t,
+        pub sun_path: [::c_char; 108]
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct sockaddr_storage {
+        pub ss_family: sa_family_t,
+        __ss_align: ::size_t,
+        __ss_pad2: [u8; 128 - 2 * 8],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct utsname {
+        pub sysname: [::c_char; 65],
+        pub nodename: [::c_char; 65],
+        pub release: [::c_char; 65],
+        pub version: [::c_char; 65],
+        pub machine: [::c_char; 65],
+        pub domainname: [::c_char; 65]
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct dirent {
+        pub d_ino: ::ino_t,
+        pub d_off: ::off_t,
+        pub d_reclen: ::c_ushort,
+        pub d_type: ::c_uchar,
+        pub d_name: [::c_char; 256],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct dirent64 {
+        pub d_ino: ::ino64_t,
+        pub d_off: ::off64_t,
+        pub d_reclen: ::c_ushort,
+        pub d_type: ::c_uchar,
+        pub d_name: [::c_char; 256],
+    }
+}
+
 // PUB_CONST
 
 pub const INT_MIN: c_int = -2147483648;
@@ -4120,14 +4009,26 @@ cfg_if! {
 }
 
 cfg_if! {
-    if #[cfg(core_cvoid)] {
-        pub use core::ffi::c_void;
+    if #[cfg(libc_align)] {
+        #[macro_use]
+        mod align;
+    } else {
+        #[macro_use]
+        mod no_align;
+    }
+}
+expand_align!();
+
+cfg_if! {
+    if #[cfg(libc_core_cvoid)] {
+        pub use ::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)]
         #[allow(missing_copy_implementations)]
+        #[allow(missing_debug_implementations)]
         pub enum c_void {
             // Two dummy variants so the #[repr] attribute can be used.
             #[doc(hidden)]
diff --git a/src/fuchsia/no_align.rs b/src/fuchsia/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..1b8db5354eb8b8558858f7cb22a44f9e2fc12407
--- /dev/null
+++ b/src/fuchsia/no_align.rs
@@ -0,0 +1,53 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            pub struct pthread_mutexattr_t {
+                #[cfg(target_arch = "x86_64")]
+                __align: [::c_int; 0],
+                #[cfg(not(target_arch = "x86_64"))]
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            pub struct pthread_rwlockattr_t {
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T],
+            }
+
+            pub struct pthread_condattr_t {
+                __align: [::c_int; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+
+        s_no_extra_traits! {
+            #[allow(missing_debug_implementations)]
+            pub struct pthread_mutex_t {
+                #[cfg(any(target_arch = "arm",
+                          all(target_arch = "x86_64",
+                              target_pointer_width = "32")))]
+                __align: [::c_long; 0],
+                #[cfg(not(any(target_arch = "arm",
+                              all(target_arch = "x86_64",
+                                  target_pointer_width = "32"))))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            #[allow(missing_debug_implementations)]
+            pub struct pthread_rwlock_t {
+                __align: [::c_long; 0],
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+
+            #[allow(missing_debug_implementations)]
+            pub struct pthread_cond_t {
+                __align: [*const ::c_void; 0],
+                #[cfg(not(target_env = "musl"))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+        }
+    }
+}
diff --git a/src/fuchsia/x86_64.rs b/src/fuchsia/x86_64.rs
index 2e4ecccbf7909871a1ad01d6442b98d2ce60ae98..8c0dc55ac2b8faaefda30e7ce1ce636f2f5500a1 100644
--- a/src/fuchsia/x86_64.rs
+++ b/src/fuchsia/x86_64.rs
@@ -51,15 +51,6 @@ s! {
         __private: [u64; 32],
     }
 
-    pub struct ucontext_t {
-        pub uc_flags: ::c_ulong,
-        pub uc_link: *mut ucontext_t,
-        pub uc_stack: ::stack_t,
-        pub uc_mcontext: mcontext_t,
-        pub uc_sigmask: ::sigset_t,
-        __private: [u8; 512],
-    }
-
     pub struct ipc_perm {
         pub __ipc_perm_key: ::key_t,
         pub uid: ::uid_t,
@@ -73,6 +64,18 @@ s! {
     }
 }
 
+s_no_extra_traits! {
+    #[allow(missing_debug_implementations)]
+    pub struct ucontext_t {
+        pub uc_flags: ::c_ulong,
+        pub uc_link: *mut ucontext_t,
+        pub uc_stack: ::stack_t,
+        pub uc_mcontext: mcontext_t,
+        pub uc_sigmask: ::sigset_t,
+        __private: [u8; 512],
+    }
+}
+
 // Syscall table
 
 pub const SYS_read: ::c_long = 0;
diff --git a/src/lib.rs b/src/lib.rs
index f46d6e263dede21d05b5ec70d462007fc364a264..72e93aaf62defa226027a723af426ef87e98b27a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -10,7 +10,7 @@
 
 //! Crate docs
 
-#![allow(bad_style, overflowing_literals, improper_ctypes)]
+#![allow(bad_style, overflowing_literals, improper_ctypes, unknown_lints)]
 #![crate_type = "rlib"]
 #![crate_name = "libc"]
 #![cfg_attr(cross_platform_docs, feature(no_core, lang_items, const_fn))]
@@ -151,7 +151,7 @@
 )]
 // Attributes needed when building as part of the standard library
 #![cfg_attr(feature = "rustc-dep-of-std", feature(cfg_target_vendor))]
-#![cfg_attr(feature = "rustc-dep-of-std", feature(link_cfg, repr_packed))]
+#![cfg_attr(feature = "rustc-dep-of-std", feature(link_cfg))]
 #![cfg_attr(feature = "rustc-dep-of-std", feature(no_core))]
 #![cfg_attr(feature = "rustc-dep-of-std", no_core)]
 #![cfg_attr(feature = "rustc-dep-of-std", allow(warnings))]
@@ -161,23 +161,56 @@
 )]
 // Enable lints
 #![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
-#![deny(missing_copy_implementations)]
-
+#![deny(missing_copy_implementations, safe_packed_borrows)]
 #[cfg(all(not(cross_platform_docs), feature = "use_std"))]
 extern crate std as core;
 
-#[cfg(feature = "rustc-dep-of-std")]
-extern crate rustc_std_workspace_core as core;
-#[cfg(feature = "rustc-dep-of-std")]
-#[allow(unused_imports)]
-use core::iter;
-#[cfg(feature = "rustc-dep-of-std")]
-#[allow(unused_imports)]
-use core::option;
-
 #[macro_use]
 mod macros;
 
+cfg_if! {
+    if #[cfg(feature = "rustc-dep-of-std")] {
+        extern crate rustc_std_workspace_core as core;
+        #[allow(unused_imports)]
+        use core::iter;
+        #[allow(unused_imports)]
+        use core::option;
+    }
+}
+
+cfg_if! {
+    if #[cfg(not(cross_platform_docs))] {
+        cfg_if! {
+            if #[cfg(libc_priv_mod_use)] {
+                #[cfg(libc_core_cvoid)]
+                #[allow(unused_imports)]
+                use core::ffi;
+                #[allow(unused_imports)]
+                use core::fmt;
+                #[allow(unused_imports)]
+                use core::hash;
+                #[allow(unused_imports)]
+                use core::num;
+                #[allow(unused_imports)]
+                use core::mem;
+            } else {
+                #[doc(hidden)]
+                #[allow(unused_imports)]
+                pub use core::fmt;
+                #[doc(hidden)]
+                #[allow(unused_imports)]
+                pub use core::hash;
+                #[doc(hidden)]
+                #[allow(unused_imports)]
+                pub use core::num;
+                #[doc(hidden)]
+                #[allow(unused_imports)]
+                pub use core::mem;
+            }
+        }
+    }
+}
+
 mod dox;
 
 cfg_if! {
diff --git a/src/macros.rs b/src/macros.rs
index 29cf4c17f00b360a2206990d4ac8bba5630aff68..89eaeb5e0315712f3f8ef6b7ff02ae89b1ae1d5d 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -6,61 +6,116 @@
 ///
 /// This allows you to conveniently provide a long list #[cfg]'d blocks of code
 /// without having to rewrite each clause multiple times.
+#[allow(unused_macros)]
 macro_rules! cfg_if {
+    // match if/else chains with a final `else`
     ($(
         if #[cfg($($meta:meta),*)] { $($it:item)* }
     ) else * else {
         $($it2:item)*
     }) => {
-        __cfg_if_items! {
+        cfg_if! {
+            @__items
             () ;
             $( ( ($($meta),*) ($($it)*) ), )*
             ( () ($($it2)*) ),
         }
-    }
-}
+    };
 
-macro_rules! __cfg_if_items {
-    (($($not:meta,)*) ; ) => {};
-    (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
-        __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* }
-        __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* }
-    }
-}
+    // match if/else chains lacking a final `else`
+    (
+        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
+        $(
+            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
+        )*
+    ) => {
+        cfg_if! {
+            @__items
+            () ;
+            ( ($($i_met),*) ($($i_it)*) ),
+            $( ( ($($e_met),*) ($($e_it)*) ), )*
+            ( () () ),
+        }
+    };
+
+    // Internal and recursive macro to emit all the items
+    //
+    // Collects all the negated cfgs in a list at the beginning and after the
+    // semicolon is all the remaining items
+    (@__items ($($not:meta,)*) ; ) => {};
+    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ),
+     $($rest:tt)*) => {
+        // Emit all items within one block, applying an approprate #[cfg]. The
+        // #[cfg] will require all `$m` matchers specified and must also negate
+        // all previous matchers.
+        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
+
+        // Recurse to emit all other items in `$rest`, and when we do so add all
+        // our `$m` matchers to the list of `$not` matchers as future emissions
+        // will have to negate everything we just matched as well.
+        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
+    };
 
-macro_rules! __cfg_if_apply {
-    ($m:meta, $($it:item)*) => {
+    // Internal macro to Apply a cfg attribute to a list of items
+    (@__apply $m:meta, $($it:item)*) => {
         $(#[$m] $it)*
-    }
+    };
 }
 
+#[allow(unused_macros)]
 macro_rules! s {
     ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($(
+        s!(it: $(#[$attr])* pub $t $i { $($field)* });
+    )*);
+    (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => (
+        compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
+    );
+    (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => (
         __item! {
             #[repr(C)]
-            $(#[$attr])*
             #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))]
-            pub $t $i { $($field)* }
+            $(#[$attr])*
+            pub struct $i { $($field)* }
         }
         impl ::dox::Copy for $i {}
         impl ::dox::Clone for $i {
             fn clone(&self) -> $i { *self }
         }
-    )*)
+    );
 }
 
+#[allow(unused_macros)]
 macro_rules! s_no_extra_traits {
     ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($(
+        s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* });
+    )*);
+    (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => (
+        cfg_if! {
+            if #[cfg(libc_union)] {
+                __item! {
+                    #[repr(C)]
+                    $(#[$attr])*
+                    pub union $i { $($field)* }
+                }
+
+                impl ::dox::Copy for $i {}
+                impl ::dox::Clone for $i {
+                    fn clone(&self) -> $i { *self }
+                }
+            }
+        }
+    );
+    (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => (
         __item! {
             #[repr(C)]
             $(#[$attr])*
-            pub $t $i { $($field)* }
+            pub struct $i { $($field)* }
         }
         impl ::dox::Copy for $i {}
         impl ::dox::Clone for $i {
             fn clone(&self) -> $i { *self }
         }
-    )*)
+    );
 }
 
 #[allow(unused_macros)]
@@ -82,6 +137,7 @@ macro_rules! f {
     )*)
 }
 
+#[allow(unused_macros)]
 macro_rules! __item {
     ($i:item) => {
         $i
@@ -93,12 +149,12 @@ macro_rules! align_const {
     ($($(#[$attr:meta])*
        pub const $name:ident : $t1:ty
        = $t2:ident { $($field:tt)* };)*) => ($(
-        #[cfg(feature = "align")]
+        #[cfg(libc_align)]
         $(#[$attr])*
         pub const $name : $t1 = $t2 {
             $($field)*
         };
-        #[cfg(not(feature = "align"))]
+        #[cfg(not(libc_align))]
         $(#[$attr])*
         pub const $name : $t1 = $t2 {
             $($field)*
diff --git a/src/redox/align.rs b/src/redox/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4fdba9a6aba6927d096c0cbc506b1f7ad94da0d0
--- /dev/null
+++ b/src/redox/align.rs
@@ -0,0 +1,6 @@
+s! {
+    #[repr(align(4))]
+    pub struct in6_addr {
+        pub s6_addr: [u8; 16],
+    }
+}
diff --git a/src/redox/mod.rs b/src/redox/mod.rs
index 82782bc16404ecf5e600bffa718ce1eb583fb9e1..cde619e98726e250a60f2036235c514e26cef504 100644
--- a/src/redox/mod.rs
+++ b/src/redox/mod.rs
@@ -386,14 +386,15 @@ pub use self::net::*;
 mod net;
 
 cfg_if! {
-    if #[cfg(core_cvoid)] {
-        pub use core::ffi::c_void;
+    if #[cfg(libc_core_cvoid)] {
+        pub use ::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)]
         #[allow(missing_copy_implementations)]
+        #[allow(missing_debug_implementations)]
         pub enum c_void {
             // Two dummy variants so the #[repr] attribute can be used.
             #[doc(hidden)]
@@ -403,3 +404,13 @@ cfg_if! {
         }
     }
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        mod align;
+        pub use self::align::*;
+    } else {
+        mod no_align;
+        pub use self::no_align::*;
+    }
+}
diff --git a/src/redox/net.rs b/src/redox/net.rs
index fcbb181c3297db5abcf16bbaecaf135d79b7fd41..5d962b1649e0b9d6a4ef7a36dcaacd90e36fa9f8 100644
--- a/src/redox/net.rs
+++ b/src/redox/net.rs
@@ -9,20 +9,13 @@ s! {
         pub s_addr: in_addr_t,
     }
 
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct in6_addr {
-        pub s6_addr: [u8; 16],
-        #[cfg(not(feature = "align"))]
-        __align: [u32; 0],
-    }
-
     pub struct ip_mreq {
         pub imr_multiaddr: in_addr,
         pub imr_interface: in_addr,
     }
 
     pub struct ipv6_mreq {
-        pub ipv6mr_multiaddr: in6_addr,
+        pub ipv6mr_multiaddr: ::in6_addr,
         pub ipv6mr_interface: ::c_uint,
     }
 
diff --git a/src/redox/no_align.rs b/src/redox/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..f6b9f4c12d4bab7e069ff89b08f878362b31d98e
--- /dev/null
+++ b/src/redox/no_align.rs
@@ -0,0 +1,6 @@
+s! {
+    pub struct in6_addr {
+        pub s6_addr: [u8; 16],
+        __align: [u32; 0],
+    }
+}
diff --git a/src/sgx.rs b/src/sgx.rs
index 1d5ca21292e9fd4758552f4f94968b3f4c7394bc..8a69ad36e48b6c09d6d2dbbe8dcd75691509f336 100644
--- a/src/sgx.rs
+++ b/src/sgx.rs
@@ -36,14 +36,15 @@ pub const INT_MIN: c_int = -2147483648;
 pub const INT_MAX: c_int = 2147483647;
 
 cfg_if! {
-    if #[cfg(core_cvoid)] {
-        pub use core::ffi::c_void;
+    if #[cfg(libc_core_cvoid)] {
+        pub use ::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)]
         #[allow(missing_copy_implementations)]
+        #[allow(missing_debug_implementations)]
         pub enum c_void {
             // Two dummy variants so the #[repr] attribute can be used.
             #[doc(hidden)]
diff --git a/src/switch.rs b/src/switch.rs
index 89e259ea27ca26b3c43d916971857ed833561248..06fa2030cdf569956fa773d2bc835338ab74bb8a 100644
--- a/src/switch.rs
+++ b/src/switch.rs
@@ -38,14 +38,15 @@ pub const INT_MIN: c_int = -2147483648;
 pub const INT_MAX: c_int = 2147483647;
 
 cfg_if! {
-    if #[cfg(core_cvoid)] {
-        pub use core::ffi::c_void;
+    if #[cfg(libc_core_cvoid)] {
+        pub use ::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)]
         #[allow(missing_copy_implementations)]
+        #[allow(missing_debug_implementations)]
         pub enum c_void {
             // Two dummy variants so the #[repr] attribute can be used.
             #[doc(hidden)]
diff --git a/src/unix/align.rs b/src/unix/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4fdba9a6aba6927d096c0cbc506b1f7ad94da0d0
--- /dev/null
+++ b/src/unix/align.rs
@@ -0,0 +1,6 @@
+s! {
+    #[repr(align(4))]
+    pub struct in6_addr {
+        pub s6_addr: [u8; 16],
+    }
+}
diff --git a/src/unix/bsd/apple/b32.rs b/src/unix/bsd/apple/b32.rs
index 284eae399ddecb1515b068d04e8ef84ac73f52ff..13b1a0b7c3dc643ecde790e63eb4dcf6edd2737b 100644
--- a/src/unix/bsd/apple/b32.rs
+++ b/src/unix/bsd/apple/b32.rs
@@ -52,32 +52,32 @@ s_no_extra_traits!{
     }
 }
 
-#[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 2161fc47590f999c824f30bf732c223d1f8fb217..50b48fa5ecd7f14adba68210b27b28b57b83ed82 100644
--- a/src/unix/bsd/apple/b64.rs
+++ b/src/unix/bsd/apple/b64.rs
@@ -57,32 +57,32 @@ s_no_extra_traits!{
     }
 }
 
-#[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 85332180e015d377803d611ae5fea785ad3e3ce2..670ef568b64351c6ec80a33b5edd6dc5f224c30c 100644
--- a/src/unix/bsd/apple/mod.rs
+++ b/src/unix/bsd/apple/mod.rs
@@ -42,6 +42,11 @@ impl ::dox::Clone for timezone {
 }
 
 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 @@ s! {
         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 @@ s! {
         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 @@ s! {
         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 @@ s! {
         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 @@ s_no_extra_traits!{
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for semun {
-    fn eq(&self, other: &semun) -> bool {
-        unsafe { self.val == other.val }
-    }
-}
-#[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_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 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_IMMUTABLE:     ::c_uint = 0x00020000;
 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 a780b08745f72f26e12a29034d4b735fc3ca4b04..dac614fd0a1cef594ab5df74b8d7c87b9720ad14 100644
--- a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
@@ -33,6 +33,14 @@ s! {
 }
 
 // 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 bc4da64d0e88df1b397f2465be0067736d07b9d4..99a761eeef5287bd498e2d9cd8ed5a264c25ce6b 100644
--- a/src/unix/bsd/freebsdlike/freebsd/arm.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/arm.rs
@@ -35,6 +35,13 @@ s! {
 }
 
 // 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 99f3675d8c6218de8488aaf1f5fd51e10b9b3cd4..0d0eb3f3b0ff5e674b9d4690d7c01aae1c3ccd7f 100644
--- a/src/unix/bsd/freebsdlike/freebsd/mod.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs
@@ -21,17 +21,6 @@ pub type posix_spawnattr_t = *mut ::c_void;
 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 @@ s! {
         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 @@ s! {
         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 @@ s! {
         __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 @@ s! {
         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 c06e1aec820b5e3cd6868220bc36cecd7847b058..517f2960240b8493cb0660b27fc3332f12868c12 100644
--- a/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs
@@ -31,6 +31,14 @@ s! {
 }
 
 // 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 2eaeec7660b884061604d730e1aef41f449e0a41..b31e3353618540705e18853760585783eec2cb27 100644
--- a/src/unix/bsd/freebsdlike/freebsd/x86.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/x86.rs
@@ -34,5 +34,12 @@ s! {
 }
 
 // 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 e9dcf784e4680ec81ca49baf1cc0f736cf7a54ca..89819fde3c8aa19dd6477e18ba250a35b2accac2 100644
--- a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
@@ -33,6 +33,13 @@ s! {
 }
 
 // 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 73f8852052e58cce20c956bf62da0ee39f7ef280..ca9ed982be5faad4210e7c1bf81bfa196895e4f3 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -23,6 +23,15 @@ impl ::dox::Clone for timezone {
 }
 
 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 @@ s! {
         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! {
     }
 }
 
+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 0541c5a005805ea92e3efd63ed60ec3868522d32..8b5ec8c54d766b75a92339b12417026c8b9511f9 100644
--- a/src/unix/bsd/mod.rs
+++ b/src/unix/bsd/mod.rs
@@ -137,89 +137,92 @@ s_no_extra_traits!{
 
 }
 
-#[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 764174d18ab7bd63a38e665b2b6ad93dd310c791..d03529662faa41c96a6bef6707def8986a181d44 100644
--- a/src/unix/bsd/netbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/mod.rs
@@ -39,14 +39,6 @@ s! {
         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 cda75bc5cdd864b141305ffeec6d49109d568386..e30d731bbf3cac2c84669fdb2cf4e7d079bb29fe 100644
--- a/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
@@ -8,8 +8,15 @@ pub type c_char = u8;
 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 71c2cb7b7909a0ed7612651a595d1076d2f32a59..cfcc1396472915a3e52922db8feaa1e60a5e1813 100644
--- a/src/unix/bsd/netbsdlike/netbsd/arm.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/arm.rs
@@ -8,8 +8,15 @@ pub type c_char = u8;
 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 d3acfb9394ae8e428cd8e8575ac9ea52aa0e963d..36a5366e6824c429212d1a9aa3f30e0840337dc6 100644
--- a/src/unix/bsd/netbsdlike/netbsd/mod.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs
@@ -24,14 +24,6 @@ s! {
         _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 @@ s! {
         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 @@ s! {
         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 @@ s! {
         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 @@ s! {
         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 FD_SETSIZE: usize = 0x100;
 
 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 3c682c35cf4b41afdb9c6eadfbc0dd87792e3956..10cdc73c8142a36466422483eac91cc2b43e646f 100644
--- a/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
@@ -8,8 +8,15 @@ pub type c_char = u8;
 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 4da99685f93da159129c5b334a5755924c08b12f..895e7f8908dd6cb056b251380b1f9c3d2e5db657 100644
--- a/src/unix/bsd/netbsdlike/netbsd/x86.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/x86.rs
@@ -6,5 +6,12 @@ pub type c_char = i8;
 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 af1b8f8000e8d0e6521bc89a06634c764b113fb1..e71a82c99bb57a7fc3ac9a32294005d4b6fb3011 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 c_char = i8;
 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 1c2e47dc3f98f60a35dba5b09eaec2fa84a73cc4..0d71fde26e37fbcd523f1c291747dcdf6290e941 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
@@ -17,6 +17,23 @@ pub type pthread_rwlockattr_t = *mut ::c_void;
 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 2a28c2a88a27bee05e11f152f2be68e9adf6a470..268e5af4f8d11a1c696d103f02132a4a0a49a20f 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_ulong = u64;
 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 a2a7a30a102a9d8cf953623204d4cad7e4f5000e..9bf2db83e697218a11ff5f208f5ba0844195262a 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs
@@ -26,42 +26,6 @@ s! {
         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! {
     }
 }
 
+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,13 +269,19 @@ extern {
     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;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
index b63b69fb63fc83eb8189304a262346cdd28a70ef..959c87b42792fbc11fc44b72251f2755937835ef 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_ulong = u32;
 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 581096fdfa4529268edc76a953089b6820814922..b2025a8a9c06b0439a0c35d8fa21249103929eda 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_ulong = u64;
 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;
diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs
index 94d8039006d2a56fd4191626bac0976f3630898d..e0365d913ce8c4e1fd53b51ebaff0ae2e4d3ce4b 100644
--- a/src/unix/haiku/mod.rs
+++ b/src/unix/haiku/mod.rs
@@ -39,6 +39,15 @@ impl ::dox::Clone for timezone {
 }
 
 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 sockaddr {
         pub sa_len: u8,
         pub sa_family: sa_family_t,
diff --git a/src/unix/hermit/mod.rs b/src/unix/hermit/mod.rs
index ba7a90f7be3688f06aab69840dc84f01afc01b14..ca389f06c1e128604b1616114c4a97f0f9b38a77 100644
--- a/src/unix/hermit/mod.rs
+++ b/src/unix/hermit/mod.rs
@@ -50,6 +50,15 @@ pub type pthread_rwlock_t = usize;
 pub type pthread_rwlockattr_t = usize;
 
 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 addrinfo {
         pub ai_flags: ::c_int,
         pub ai_family: ::c_int,
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index 409f2835fd04dde81cc6deaa8ea8b33d8ca56c8a..24779c9b3a5d4cd26d1e0d6543db0d180e1e3a91 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -137,23 +137,6 @@ s! {
         __reserved: [c_long; 16],
     }
 
-    #[cfg_attr(target_os = "netbsd", repr(packed))]
-    pub struct in_addr {
-        pub s_addr: in_addr_t,
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct in6_addr {
-        pub s6_addr: [u8; 16],
-        #[cfg(not(feature = "align"))]
-        __align: [u32; 0],
-    }
-
-    pub struct ip_mreq {
-        pub imr_multiaddr: in_addr,
-        pub imr_interface: in_addr,
-    }
-
     pub struct ipv6_mreq {
         pub ipv6mr_multiaddr: in6_addr,
         #[cfg(target_os = "android")]
@@ -1169,14 +1152,15 @@ cfg_if! {
 }
 
 cfg_if! {
-    if #[cfg(core_cvoid)] {
-        pub use core::ffi::c_void;
+    if #[cfg(libc_core_cvoid)] {
+        pub use ::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)]
         #[allow(missing_copy_implementations)]
+        #[allow(missing_debug_implementations)]
         pub enum c_void {
             // Two dummy variants so the #[repr] attribute can be used.
             #[doc(hidden)]
@@ -1186,3 +1170,13 @@ cfg_if! {
         }
     }
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        mod align;
+        pub use self::align::*;
+    } else {
+        mod no_align;
+        pub use self::no_align::*;
+    }
+}
diff --git a/src/unix/newlib/align.rs b/src/unix/newlib/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c018fbcbb09d0f6a70ef895a4c2467f2b3de4f75
--- /dev/null
+++ b/src/unix/newlib/align.rs
@@ -0,0 +1,61 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "mips",
+                               target_arch = "arm",
+                               target_arch = "powerpc")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "mips",
+                                   target_arch = "arm",
+                                   target_arch = "powerpc"))),
+                       repr(align(8)))]
+            pub struct pthread_mutex_t { // Unverified
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "mips",
+                               target_arch = "arm",
+                               target_arch = "powerpc")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "mips",
+                                   target_arch = "arm",
+                                   target_arch = "powerpc"))),
+                       repr(align(8)))]
+            pub struct pthread_rwlock_t { // Unverified
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+
+            #[cfg_attr(any(target_pointer_width = "32",
+                           target_arch = "x86_64",
+                           target_arch = "powerpc64",
+                           target_arch = "mips64",
+                           target_arch = "s390x",
+                           target_arch = "sparc64"),
+                       repr(align(4)))]
+            #[cfg_attr(not(any(target_pointer_width = "32",
+                               target_arch = "x86_64",
+                               target_arch = "powerpc64",
+                               target_arch = "mips64",
+                               target_arch = "s390x",
+                               target_arch = "sparc64")),
+                       repr(align(8)))]
+            pub struct pthread_mutexattr_t { // Unverified
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            #[repr(align(8))]
+            pub struct pthread_cond_t { // Unverified
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_condattr_t { // Unverified
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/newlib/mod.rs b/src/unix/newlib/mod.rs
index 0cc411d6a67b7b5ebf2414038f8419d892e1ca7f..94bce1e12f467c0c318247e0821a90633d41d33d 100644
--- a/src/unix/newlib/mod.rs
+++ b/src/unix/newlib/mod.rs
@@ -27,6 +27,15 @@ pub type time_t = i32;
 pub type useconds_t = u32;
 
 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 sockaddr {
         pub sa_family: sa_family_t,
         pub sa_data: [::c_char; 14],
@@ -238,103 +247,10 @@ s! {
         __size: [u64; 7]
     }
 
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "mips",
-                       target_arch = "arm",
-                       target_arch = "powerpc")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "mips",
-                               target_arch = "arm",
-                               target_arch = "powerpc")))),
-               repr(align(8)))]
-    pub struct pthread_mutex_t { // Unverified
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "mips",
-                       target_arch = "arm",
-                       target_arch = "powerpc")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "mips",
-                               target_arch = "arm",
-                               target_arch = "powerpc")))),
-               repr(align(8)))]
-    pub struct pthread_rwlock_t { // Unverified
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCK_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "32",
-                       target_arch = "x86_64", target_arch = "powerpc64",
-                       target_arch = "mips64", target_arch = "s390x",
-                       target_arch = "sparc64")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(any(target_pointer_width = "32",
-                           target_arch = "x86_64", target_arch = "powerpc64",
-                           target_arch = "mips64", target_arch = "s390x",
-                           target_arch = "sparc64"))),
-               repr(align(8)))]
-    pub struct pthread_mutexattr_t { // Unverified
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "x86_64", target_arch = "powerpc64",
-                      target_arch = "mips64", target_arch = "s390x",
-                      target_arch = "sparc64")))]
-        __align: [::c_int; 0],
-        #[cfg(all(not(feature = "align"),
-                  not(any(target_arch = "x86_64", target_arch = "powerpc64",
-                          target_arch = "mips64", target_arch = "s390x",
-                          target_arch = "sparc64"))))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
-    }
-
     pub struct pthread_rwlockattr_t { // Unverified
         __lockkind: ::c_int,
         __pshared: ::c_int,
     }
-
-    #[cfg_attr(feature = "align", repr(align(8)))]
-    pub struct pthread_cond_t { // Unverified
-        #[cfg(not(feature = "align"))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_COND_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_condattr_t { // Unverified
-        #[cfg(not(feature = "align"))]
-        __align: [::c_int; 0],
-        size: [u8; __SIZEOF_PTHREAD_CONDATTR_T],
-    }
-
 }
 
 // unverified constants
@@ -744,3 +660,14 @@ cfg_if! {
         pub use target_arch_not_implemented;
     }
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        #[macro_use]
+        mod align;
+    } else {
+        #[macro_use]
+        mod no_align;
+    }
+}
+expand_align!();
diff --git a/src/unix/newlib/no_align.rs b/src/unix/newlib/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..316c464ed59a89e5bb143723b81f094d45cacf3c
--- /dev/null
+++ b/src/unix/newlib/no_align.rs
@@ -0,0 +1,51 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            pub struct pthread_mutex_t { // Unverified
+                #[cfg(any(target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc"))]
+                __align: [::c_long; 0],
+                #[cfg(not(any(target_arch = "mips",
+                              target_arch = "arm",
+                              target_arch = "powerpc")))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            pub struct pthread_rwlock_t { // Unverified
+                #[cfg(any(target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc"))]
+                __align: [::c_long; 0],
+                #[cfg(not(any(target_arch = "mips",
+                              target_arch = "arm",
+                              target_arch = "powerpc")))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+
+            pub struct pthread_mutexattr_t { // Unverified
+                #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64",
+                          target_arch = "mips64", target_arch = "s390x",
+                          target_arch = "sparc64"))]
+                __align: [::c_int; 0],
+                #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64",
+                              target_arch = "mips64", target_arch = "s390x",
+                              target_arch = "sparc64")))]
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            pub struct pthread_cond_t { // Unverified
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+
+            pub struct pthread_condattr_t { // Unverified
+                __align: [::c_int; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/no_align.rs b/src/unix/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..f6b9f4c12d4bab7e069ff89b08f878362b31d98e
--- /dev/null
+++ b/src/unix/no_align.rs
@@ -0,0 +1,6 @@
+s! {
+    pub struct in6_addr {
+        pub s6_addr: [u8; 16],
+        __align: [u32; 0],
+    }
+}
diff --git a/src/unix/notbsd/android/b64/mod.rs b/src/unix/notbsd/android/b64/mod.rs
index 1da667bccc0c2b1b3b8c9105ca34a645b9308f57..fce9965b0017a71d6092cae06ff272772798865f 100644
--- a/src/unix/notbsd/android/b64/mod.rs
+++ b/src/unix/notbsd/android/b64/mod.rs
@@ -127,103 +127,107 @@ s_no_extra_traits!{
         __reserved: [::c_char; 36],
     }
 }
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_mutex_t {
-    fn eq(&self, other: &pthread_mutex_t) -> bool {
-        self.value == other.value
-            && self
-                .__reserved
-                .iter()
-                .zip(other.__reserved.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("value", &self.value)
-            // FIXME: .field("__reserved", &self.__reserved)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_mutex_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.value.hash(state);
-        self.__reserved.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_cond_t {
-    fn eq(&self, other: &pthread_cond_t) -> bool {
-        self.value == other.value
-            && self
-                .__reserved
-                .iter()
-                .zip(other.__reserved.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("value", &self.value)
-            // FIXME: .field("__reserved", &self.__reserved)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_cond_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.value.hash(state);
-        self.__reserved.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_rwlock_t {
-    fn eq(&self, other: &pthread_rwlock_t) -> bool {
-        self.numLocks == other.numLocks
-            && self.writerThreadId == other.writerThreadId
-            && self.pendingReaders == other.pendingReaders
-            && self.pendingWriters == other.pendingWriters
-            && self.attr == other.attr
-            && self
-                .__reserved
-                .iter()
-                .zip(other.__reserved.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("numLocks", &self.numLocks)
-            .field("writerThreadId", &self.writerThreadId)
-            .field("pendingReaders", &self.pendingReaders)
-            .field("pendingWriters", &self.pendingWriters)
-            .field("attr", &self.attr)
-            // FIXME: .field("__reserved", &self.__reserved)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_rwlock_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.numLocks.hash(state);
-        self.writerThreadId.hash(state);
-        self.pendingReaders.hash(state);
-        self.pendingWriters.hash(state);
-        self.attr.hash(state);
-        self.__reserved.hash(state);
+
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for pthread_mutex_t {
+            fn eq(&self, other: &pthread_mutex_t) -> bool {
+                self.value == other.value
+                    && self
+                    .__reserved
+                    .iter()
+                    .zip(other.__reserved.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("value", &self.value)
+                    // FIXME: .field("__reserved", &self.__reserved)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for pthread_mutex_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.value.hash(state);
+                self.__reserved.hash(state);
+            }
+        }
+
+        impl PartialEq for pthread_cond_t {
+            fn eq(&self, other: &pthread_cond_t) -> bool {
+                self.value == other.value
+                    && self
+                    .__reserved
+                    .iter()
+                    .zip(other.__reserved.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("value", &self.value)
+                    // FIXME: .field("__reserved", &self.__reserved)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for pthread_cond_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.value.hash(state);
+                self.__reserved.hash(state);
+            }
+        }
+
+        impl PartialEq for pthread_rwlock_t {
+            fn eq(&self, other: &pthread_rwlock_t) -> bool {
+                self.numLocks == other.numLocks
+                    && self.writerThreadId == other.writerThreadId
+                    && self.pendingReaders == other.pendingReaders
+                    && self.pendingWriters == other.pendingWriters
+                    && self.attr == other.attr
+                    && self
+                    .__reserved
+                    .iter()
+                    .zip(other.__reserved.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("numLocks", &self.numLocks)
+                    .field("writerThreadId", &self.writerThreadId)
+                    .field("pendingReaders", &self.pendingReaders)
+                    .field("pendingWriters", &self.pendingWriters)
+                    .field("attr", &self.attr)
+                    // FIXME: .field("__reserved", &self.__reserved)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for pthread_rwlock_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.numLocks.hash(state);
+                self.writerThreadId.hash(state);
+                self.pendingReaders.hash(state);
+                self.pendingWriters.hash(state);
+                self.attr.hash(state);
+                self.__reserved.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/notbsd/android/mod.rs b/src/unix/notbsd/android/mod.rs
index f768ce1283e0e8930792968c720ea8892a0a5e49..2213b75b663ed4164bcd192842e92f202b931b1c 100644
--- a/src/unix/notbsd/android/mod.rs
+++ b/src/unix/notbsd/android/mod.rs
@@ -240,214 +240,217 @@ s_no_extra_traits!{
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for dirent {
-    fn eq(&self, other: &dirent) -> bool {
-        self.d_ino == other.d_ino
-            && self.d_off == other.d_off
-            && self.d_reclen == other.d_reclen
-            && 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_off", &self.d_off)
-            .field("d_reclen", &self.d_reclen)
-            .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_off.hash(state);
-        self.d_reclen.hash(state);
-        self.d_type.hash(state);
-        self.d_name.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for dirent64 {
-    fn eq(&self, other: &dirent64) -> bool {
-        self.d_ino == other.d_ino
-            && self.d_off == other.d_off
-            && self.d_reclen == other.d_reclen
-            && 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 dirent64 {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for dirent64 {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("dirent64")
-            .field("d_ino", &self.d_ino)
-            .field("d_off", &self.d_off)
-            .field("d_reclen", &self.d_reclen)
-            .field("d_type", &self.d_type)
-            // FIXME: .field("d_name", &self.d_name)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for dirent64 {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.d_ino.hash(state);
-        self.d_off.hash(state);
-        self.d_reclen.hash(state);
-        self.d_type.hash(state);
-        self.d_name.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for siginfo_t {
-    fn eq(&self, other: &siginfo_t) -> bool {
-        self.si_signo == other.si_signo
-            && self.si_errno == other.si_errno
-            && self.si_code == other.si_code
-            // Ignore _pad
-            // Ignore _align
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for siginfo_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for siginfo_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("siginfo_t")
-            .field("si_signo", &self.si_signo)
-            .field("si_errno", &self.si_errno)
-            .field("si_code", &self.si_code)
-            // Ignore _pad
-            // Ignore _align
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for siginfo_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.si_signo.hash(state);
-        self.si_errno.hash(state);
-        self.si_code.hash(state);
-            // Ignore _pad
-            // Ignore _align
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for lastlog {
-    fn eq(&self, other: &lastlog) -> bool {
-        self.ll_time == other.ll_time
-            && self
-                .ll_line
-                .iter()
-                .zip(other.ll_line.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .ll_host
-                .iter()
-                .zip(other.ll_host.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for lastlog {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for lastlog {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("lastlog")
-            .field("ll_time", &self.ll_time)
-            .field("ll_line", &self.ll_line)
-            // FIXME: .field("ll_host", &self.ll_host)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for lastlog {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.ll_time.hash(state);
-        self.ll_line.hash(state);
-        self.ll_host.hash(state);
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for utmp {
-    fn eq(&self, other: &utmp) -> bool {
-        self.ut_type == other.ut_type
-            && self.ut_pid == other.ut_pid
-            && self
-                .ut_line
-                .iter()
-                .zip(other.ut_line.iter())
-                .all(|(a,b)| a == b)
-            && self.ut_id == other.ut_id
-            && self
-                .ut_user
-                .iter()
-                .zip(other.ut_user.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .ut_host
-                .iter()
-                .zip(other.ut_host.iter())
-                .all(|(a,b)| a == b)
-            && self.ut_exit == other.ut_exit
-            && self.ut_session == other.ut_session
-            && self.ut_tv == other.ut_tv
-            && self.ut_addr_v6 == other.ut_addr_v6
-            && self.unused == other.unused
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for utmp {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for utmp {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("utmp")
-            .field("ut_type", &self.ut_type)
-            .field("ut_pid", &self.ut_pid)
-            .field("ut_line", &self.ut_line)
-            .field("ut_id", &self.ut_id)
-            .field("ut_user", &self.ut_user)
-            // FIXME: .field("ut_host", &self.ut_host)
-            .field("ut_exit", &self.ut_exit)
-            .field("ut_session", &self.ut_session)
-            .field("ut_tv", &self.ut_tv)
-            .field("ut_addr_v6", &self.ut_addr_v6)
-            .field("unused", &self.unused)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for utmp {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.ut_type.hash(state);
-        self.ut_pid.hash(state);
-        self.ut_line.hash(state);
-        self.ut_id.hash(state);
-        self.ut_user.hash(state);
-        self.ut_host.hash(state);
-        self.ut_exit.hash(state);
-        self.ut_session.hash(state);
-        self.ut_tv.hash(state);
-        self.ut_addr_v6.hash(state);
-        self.unused.hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && 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_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .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_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent64 {
+            fn eq(&self, other: &dirent64) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && self.d_type == other.d_type
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for dirent64 {}
+
+        impl ::fmt::Debug for dirent64 {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent64")
+                    .field("d_ino", &self.d_ino)
+                    .field("d_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for dirent64 {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_ino.hash(state);
+                self.d_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for siginfo_t {
+            fn eq(&self, other: &siginfo_t) -> bool {
+                self.si_signo == other.si_signo
+                    && self.si_errno == other.si_errno
+                    && self.si_code == other.si_code
+                // Ignore _pad
+                // Ignore _align
+            }
+        }
+
+        impl Eq for siginfo_t {}
+
+        impl ::fmt::Debug for siginfo_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("siginfo_t")
+                    .field("si_signo", &self.si_signo)
+                    .field("si_errno", &self.si_errno)
+                    .field("si_code", &self.si_code)
+                // Ignore _pad
+                // Ignore _align
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for siginfo_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.si_signo.hash(state);
+                self.si_errno.hash(state);
+                self.si_code.hash(state);
+                // Ignore _pad
+                // Ignore _align
+            }
+        }
+
+        impl PartialEq for lastlog {
+            fn eq(&self, other: &lastlog) -> bool {
+                self.ll_time == other.ll_time
+                    && self
+                    .ll_line
+                    .iter()
+                    .zip(other.ll_line.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .ll_host
+                    .iter()
+                    .zip(other.ll_host.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for lastlog {}
+
+        impl ::fmt::Debug for lastlog {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("lastlog")
+                    .field("ll_time", &self.ll_time)
+                    .field("ll_line", &self.ll_line)
+                // FIXME: .field("ll_host", &self.ll_host)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for lastlog {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ll_time.hash(state);
+                self.ll_line.hash(state);
+                self.ll_host.hash(state);
+            }
+        }
+
+        impl PartialEq for utmp {
+            fn eq(&self, other: &utmp) -> bool {
+                self.ut_type == other.ut_type
+                    && self.ut_pid == other.ut_pid
+                    && self
+                    .ut_line
+                    .iter()
+                    .zip(other.ut_line.iter())
+                    .all(|(a,b)| a == b)
+                    && self.ut_id == other.ut_id
+                    && self
+                    .ut_user
+                    .iter()
+                    .zip(other.ut_user.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .ut_host
+                    .iter()
+                    .zip(other.ut_host.iter())
+                    .all(|(a,b)| a == b)
+                    && self.ut_exit == other.ut_exit
+                    && self.ut_session == other.ut_session
+                    && self.ut_tv == other.ut_tv
+                    && self.ut_addr_v6 == other.ut_addr_v6
+                    && self.unused == other.unused
+            }
+        }
+
+        impl Eq for utmp {}
+
+        impl ::fmt::Debug for utmp {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utmp")
+                    .field("ut_type", &self.ut_type)
+                    .field("ut_pid", &self.ut_pid)
+                    .field("ut_line", &self.ut_line)
+                    .field("ut_id", &self.ut_id)
+                    .field("ut_user", &self.ut_user)
+                // FIXME: .field("ut_host", &self.ut_host)
+                    .field("ut_exit", &self.ut_exit)
+                    .field("ut_session", &self.ut_session)
+                    .field("ut_tv", &self.ut_tv)
+                    .field("ut_addr_v6", &self.ut_addr_v6)
+                    .field("unused", &self.unused)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for utmp {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ut_type.hash(state);
+                self.ut_pid.hash(state);
+                self.ut_line.hash(state);
+                self.ut_id.hash(state);
+                self.ut_user.hash(state);
+                self.ut_host.hash(state);
+                self.ut_exit.hash(state);
+                self.ut_session.hash(state);
+                self.ut_tv.hash(state);
+                self.ut_addr_v6.hash(state);
+                self.unused.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/notbsd/emscripten/align.rs b/src/unix/notbsd/emscripten/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3f36d45d6d71fb60114f8adcd9c3f682c583e902
--- /dev/null
+++ b/src/unix/notbsd/emscripten/align.rs
@@ -0,0 +1,41 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            #[repr(align(4))]
+            pub struct pthread_mutex_t {
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_rwlock_t {
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_mutexattr_t {
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_rwlockattr_t {
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_condattr_t {
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+
+        s_no_extra_traits! {
+            #[cfg_attr(target_pointer_width = "32",
+                       repr(align(4)))]
+            #[cfg_attr(target_pointer_width = "64",
+                       repr(align(8)))]
+            #[allow(missing_debug_implementations)]
+            pub struct pthread_cond_t {
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/notbsd/emscripten.rs b/src/unix/notbsd/emscripten/mod.rs
similarity index 97%
rename from src/unix/notbsd/emscripten.rs
rename to src/unix/notbsd/emscripten/mod.rs
index 2685e769fc1d6adb59d9fe149e24f170a26d38e3..5de7b5ac57608600db55424e1fab668adff5eb2a 100644
--- a/src/unix/notbsd/emscripten.rs
+++ b/src/unix/notbsd/emscripten/mod.rs
@@ -43,22 +43,6 @@ impl ::dox::Clone for fpos64_t {
 }
 
 s! {
-    pub struct dirent {
-        pub d_ino: ::ino_t,
-        pub d_off: ::off_t,
-        pub d_reclen: ::c_ushort,
-        pub d_type: ::c_uchar,
-        pub d_name: [::c_char; 256],
-    }
-
-    pub struct dirent64 {
-        pub d_ino: ::ino64_t,
-        pub d_off: ::off64_t,
-        pub d_reclen: ::c_ushort,
-        pub d_type: ::c_uchar,
-        pub d_name: [::c_char; 256],
-    }
-
     pub struct rlimit64 {
         pub rlim_cur: rlim64_t,
         pub rlim_max: rlim64_t,
@@ -77,51 +61,6 @@ s! {
         __unused5: *mut ::c_void,
     }
 
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_mutex_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_rwlock_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCK_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_mutexattr_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_int; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_rwlockattr_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_int; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T],
-    }
-
-    #[cfg_attr(all(feature = "align", target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align", target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct pthread_cond_t {
-        #[cfg(not(feature = "align"))]
-        __align: [*const ::c_void; 0],
-        size: [u8; __SIZEOF_PTHREAD_COND_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_condattr_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_int; 0],
-        size: [u8; __SIZEOF_PTHREAD_CONDATTR_T],
-    }
-
     pub struct passwd {
         pub pw_name: *mut ::c_char,
         pub pw_passwd: *mut ::c_char,
@@ -296,23 +235,6 @@ s! {
         pub l_pid: ::pid_t,
     }
 
-    pub struct sysinfo {
-        pub uptime: ::c_ulong,
-        pub loads: [::c_ulong; 3],
-        pub totalram: ::c_ulong,
-        pub freeram: ::c_ulong,
-        pub sharedram: ::c_ulong,
-        pub bufferram: ::c_ulong,
-        pub totalswap: ::c_ulong,
-        pub freeswap: ::c_ulong,
-        pub procs: ::c_ushort,
-        pub pad: ::c_ushort,
-        pub totalhigh: ::c_ulong,
-        pub freehigh: ::c_ulong,
-        pub mem_unit: ::c_uint,
-        pub __reserved: [::c_char; 256],
-    }
-
     pub struct pthread_attr_t {
         __size: [u32; 11]
     }
@@ -487,6 +409,44 @@ s! {
     }
 }
 
+s_no_extra_traits! {
+    #[allow(missing_debug_implementations)]
+    pub struct dirent {
+        pub d_ino: ::ino_t,
+        pub d_off: ::off_t,
+        pub d_reclen: ::c_ushort,
+        pub d_type: ::c_uchar,
+        pub d_name: [::c_char; 256],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct dirent64 {
+        pub d_ino: ::ino64_t,
+        pub d_off: ::off64_t,
+        pub d_reclen: ::c_ushort,
+        pub d_type: ::c_uchar,
+        pub d_name: [::c_char; 256],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct sysinfo {
+        pub uptime: ::c_ulong,
+        pub loads: [::c_ulong; 3],
+        pub totalram: ::c_ulong,
+        pub freeram: ::c_ulong,
+        pub sharedram: ::c_ulong,
+        pub bufferram: ::c_ulong,
+        pub totalswap: ::c_ulong,
+        pub freeswap: ::c_ulong,
+        pub procs: ::c_ushort,
+        pub pad: ::c_ushort,
+        pub totalhigh: ::c_ulong,
+        pub freehigh: ::c_ulong,
+        pub mem_unit: ::c_uint,
+        pub __reserved: [::c_char; 256],
+    }
+}
+
 pub const ABDAY_1: ::nl_item = 0x20000;
 pub const ABDAY_2: ::nl_item = 0x20001;
 pub const ABDAY_3: ::nl_item = 0x20002;
@@ -1701,3 +1661,14 @@ extern {
                           f: extern fn(*mut ::c_void) -> *mut ::c_void,
                           value: *mut ::c_void) -> ::c_int;
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        #[macro_use]
+        mod align;
+    } else {
+        #[macro_use]
+        mod no_align;
+    }
+}
+expand_align!();
diff --git a/src/unix/notbsd/emscripten/no_align.rs b/src/unix/notbsd/emscripten/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..cf8880794c16842a687ed275ff50089fdbc8c6c1
--- /dev/null
+++ b/src/unix/notbsd/emscripten/no_align.rs
@@ -0,0 +1,38 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            pub struct pthread_mutex_t {
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            pub struct pthread_rwlock_t {
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+
+            pub struct pthread_mutexattr_t {
+                __align: [::c_int; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            pub struct pthread_rwlockattr_t {
+                __align: [::c_int; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T],
+            }
+
+            pub struct pthread_condattr_t {
+                __align: [::c_int; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+
+        s_no_extra_traits! {
+            #[allow(missing_debug_implementations)]
+            pub struct pthread_cond_t {
+                __align: [*const ::c_void; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/notbsd/linux/align.rs b/src/unix/notbsd/linux/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a35e26913af7fdcef48ac3819a9243dc1ecc0308
--- /dev/null
+++ b/src/unix/notbsd/linux/align.rs
@@ -0,0 +1,100 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            #[cfg_attr(any(target_pointer_width = "32",
+                           target_arch = "x86_64",
+                           target_arch = "powerpc64",
+                           target_arch = "mips64",
+                           target_arch = "s390x",
+                           target_arch = "sparc64",
+                           all(target_arch = "aarch64",
+                               target_env = "musl")),
+                       repr(align(4)))]
+            #[cfg_attr(not(any(target_pointer_width = "32",
+                               target_arch = "x86_64",
+                               target_arch = "powerpc64",
+                               target_arch = "mips64",
+                               target_arch = "s390x",
+                               target_arch = "sparc64",
+                               all(target_arch = "aarch64",
+                                   target_env = "musl"))),
+                       repr(align(8)))]
+            pub struct pthread_mutexattr_t {
+                #[doc(hidden)]
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            #[cfg_attr(any(target_env = "musl", target_pointer_width = "32"),
+                       repr(align(4)))]
+            #[cfg_attr(all(not(target_env = "musl"),
+                           target_pointer_width = "64"),
+                       repr(align(8)))]
+            pub struct pthread_rwlockattr_t {
+                #[doc(hidden)]
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_condattr_t {
+                #[doc(hidden)]
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+
+        s_no_extra_traits! {
+            #[cfg_attr(all(target_env = "musl",
+                           target_pointer_width = "32"),
+                       repr(align(4)))]
+            #[cfg_attr(all(target_env = "musl",
+                           target_pointer_width = "64"),
+                       repr(align(8)))]
+            #[cfg_attr(all(not(target_env = "musl"),
+                           target_arch = "x86"),
+                       repr(align(4)))]
+            #[cfg_attr(all(not(target_env = "musl"),
+                           not(target_arch = "x86")),
+                       repr(align(8)))]
+            pub struct pthread_cond_t {
+                #[doc(hidden)]
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "mips",
+                               target_arch = "arm",
+                               target_arch = "powerpc",
+                               target_arch = "x86_64",
+                               target_arch = "x86")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "mips",
+                                   target_arch = "arm",
+                                   target_arch = "powerpc",
+                                   target_arch = "x86_64",
+                                   target_arch = "x86"))),
+                       repr(align(8)))]
+            pub struct pthread_mutex_t {
+                #[doc(hidden)]
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "mips",
+                               target_arch = "arm",
+                               target_arch = "powerpc",
+                               target_arch = "x86_64",
+                               target_arch = "x86")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "mips",
+                                   target_arch = "arm",
+                                   target_arch = "powerpc",
+                                   target_arch = "x86_64",
+                                   target_arch = "x86"))),
+                       repr(align(8)))]
+            pub struct pthread_rwlock_t {
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/notbsd/linux/mips/align.rs b/src/unix/notbsd/linux/mips/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4a0e07460ebb10fe101ee84406726a5a2ac065a1
--- /dev/null
+++ b/src/unix/notbsd/linux/mips/align.rs
@@ -0,0 +1,13 @@
+s! {
+    // FIXME this is actually a union
+    #[cfg_attr(target_pointer_width = "32",
+               repr(align(4)))]
+    #[cfg_attr(target_pointer_width = "64",
+               repr(align(8)))]
+    pub struct sem_t {
+        #[cfg(target_pointer_width = "32")]
+        __size: [::c_char; 16],
+        #[cfg(target_pointer_width = "64")]
+        __size: [::c_char; 32],
+    }
+}
diff --git a/src/unix/notbsd/linux/mips/mod.rs b/src/unix/notbsd/linux/mips/mod.rs
index 8809bef81e87acade69e00de3544f71a5a818b60..5d4dec79bf5e7ac57f4e33145bd13b48c97c7b2b 100644
--- a/src/unix/notbsd/linux/mips/mod.rs
+++ b/src/unix/notbsd/linux/mips/mod.rs
@@ -20,20 +20,6 @@ s! {
         __unused5: *mut ::c_void,
     }
 
-    // FIXME this is actually a union
-    #[cfg_attr(all(feature = "align", target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align", target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct sem_t {
-        #[cfg(target_pointer_width = "32")]
-        __size: [::c_char; 16],
-        #[cfg(target_pointer_width = "64")]
-        __size: [::c_char; 32],
-        #[cfg(not(feature = "align"))]
-        __align: [::c_long; 0],
-    }
-
     pub struct termios2 {
         pub c_iflag: ::tcflag_t,
         pub c_oflag: ::tcflag_t,
@@ -962,3 +948,13 @@ cfg_if! {
         // Unknown target_arch
     }
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        mod align;
+        pub use self::align::*;
+    } else {
+        mod no_align;
+        pub use self::no_align::*;
+    }
+}
diff --git a/src/unix/notbsd/linux/mips/no_align.rs b/src/unix/notbsd/linux/mips/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e32bf673d140e27b412196ccc9b9554b594e2ea8
--- /dev/null
+++ b/src/unix/notbsd/linux/mips/no_align.rs
@@ -0,0 +1,10 @@
+s! {
+    // FIXME this is actually a union
+    pub struct sem_t {
+        #[cfg(target_pointer_width = "32")]
+        __size: [::c_char; 16],
+        #[cfg(target_pointer_width = "64")]
+        __size: [::c_char; 32],
+        __align: [::c_long; 0],
+    }
+}
diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs
index 034db9bc854824657230a3bf339a3ef5beb8f2e9..03192e6278e3d0e45f19206753809ee514633931 100644
--- a/src/unix/notbsd/linux/mod.rs
+++ b/src/unix/notbsd/linux/mod.rs
@@ -64,58 +64,6 @@ s! {
         __unused5: *mut ::c_void,
     }
 
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "32",
-                       target_arch = "x86_64", target_arch = "powerpc64",
-                       target_arch = "mips64", target_arch = "s390x",
-                       target_arch = "sparc64",
-                       all(target_arch = "aarch64", target_env = "musl"))),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(any(target_pointer_width = "32",
-                           target_arch = "x86_64", target_arch = "powerpc64",
-                           target_arch = "mips64", target_arch = "s390x",
-                           target_arch = "sparc64",
-                           all(target_arch = "aarch64", target_env = "musl")))),
-               repr(align(8)))]
-    pub struct pthread_mutexattr_t {
-        #[cfg(all(not(features = "align"),
-                  any(target_arch = "x86_64", target_arch = "powerpc64",
-                      target_arch = "mips64", target_arch = "s390x",
-                      target_arch = "sparc64",
-                      all(target_arch = "aarch64", target_env = "musl"))))]
-        __align: [::c_int; 0],
-        #[cfg(all(not(features = "align"),
-                  not(any(target_arch = "x86_64", target_arch = "powerpc64",
-                          target_arch = "mips64", target_arch = "s390x",
-                          target_arch = "sparc64",
-                          all(target_arch = "aarch64", target_env = "musl")))))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   any(target_env = "musl", target_pointer_width = "32")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(target_env = "musl"),
-                   target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct pthread_rwlockattr_t {
-        #[cfg(all(not(feature = "align"), target_env = "musl"))]
-        __align: [::c_int; 0],
-        #[cfg(all(not(feature = "align"), not(target_env = "musl")))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_condattr_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_int; 0],
-        size: [u8; __SIZEOF_PTHREAD_CONDATTR_T],
-    }
-
     pub struct passwd {
         pub pw_name: *mut ::c_char,
         pub pw_passwd: *mut ::c_char,
@@ -577,244 +525,151 @@ s_no_extra_traits!{
         pub d_type: ::c_uchar,
         pub d_name: [::c_char; 256],
     }
-
-    #[cfg_attr(all(feature = "align",
-                   target_env = "musl",
-                   target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   target_env = "musl",
-                   target_pointer_width = "64"),
-               repr(align(8)))]
-    #[cfg_attr(all(feature = "align",
-                   not(target_env = "musl"),
-                   target_arch = "x86"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(target_env = "musl"),
-                   not(target_arch = "x86")),
-               repr(align(8)))]
-    pub struct pthread_cond_t {
-        #[cfg(all(not(feature = "align"), target_env = "musl"))]
-        __align: [*const ::c_void; 0],
-        #[cfg(not(any(feature = "align", target_env = "musl")))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_COND_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "mips",
-                       target_arch = "arm",
-                       target_arch = "powerpc",
-                       target_arch = "x86_64",
-                       target_arch = "x86")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "mips",
-                               target_arch = "arm",
-                               target_arch = "powerpc",
-                               target_arch = "x86_64",
-                               target_arch = "x86")))),
-               repr(align(8)))]
-    pub struct pthread_mutex_t {
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc",
-                      all(target_arch = "x86_64",
-                          target_pointer_width = "32"))))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc",
-                      all(target_arch = "x86_64",
-                          target_pointer_width = "32"))))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "mips",
-                       target_arch = "arm",
-                       target_arch = "powerpc",
-                       target_arch = "x86_64",
-                       target_arch = "x86")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "mips",
-                               target_arch = "arm",
-                               target_arch = "powerpc",
-                               target_arch = "x86_64",
-                               target_arch = "x86")))),
-               repr(align(8)))]
-    pub struct pthread_rwlock_t {
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc",
-                      all(target_arch = "x86_64",
-                          target_pointer_width = "32"))))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc",
-                      all(target_arch = "x86_64",
-                          target_pointer_width = "32"))))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCK_T],
-    }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for dirent {
-    fn eq(&self, other: &dirent) -> bool {
-        self.d_ino == other.d_ino
-            && self.d_off == other.d_off
-            && self.d_reclen == other.d_reclen
-            && 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_off", &self.d_off)
-            .field("d_reclen", &self.d_reclen)
-            .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_off.hash(state);
-        self.d_reclen.hash(state);
-        self.d_type.hash(state);
-        self.d_name.hash(state);
-    }
-}
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && 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 PartialEq for dirent64 {
-    fn eq(&self, other: &dirent64) -> bool {
-        self.d_ino == other.d_ino
-            && self.d_off == other.d_off
-            && self.d_reclen == other.d_reclen
-            && 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 dirent64 {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for dirent64 {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("dirent64")
-            .field("d_ino", &self.d_ino)
-            .field("d_off", &self.d_off)
-            .field("d_reclen", &self.d_reclen)
-            .field("d_type", &self.d_type)
-            // FIXME: .field("d_name", &self.d_name)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for dirent64 {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.d_ino.hash(state);
-        self.d_off.hash(state);
-        self.d_reclen.hash(state);
-        self.d_type.hash(state);
-        self.d_name.hash(state);
-    }
-}
+        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_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_cond_t {
-    fn eq(&self, other: &pthread_cond_t) -> bool {
-        self.size.iter().zip(other.size.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")
-            // FIXME: .field("size", &self.size)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_cond_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.size.hash(state);
-    }
-}
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_ino.hash(state);
+                self.d_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for pthread_mutex_t {
-    fn eq(&self, other: &pthread_mutex_t) -> bool {
-        self.size.iter().zip(other.size.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")
-            // FIXME: .field("size", &self.size)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_mutex_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.size.hash(state);
-    }
-}
+        impl PartialEq for dirent64 {
+            fn eq(&self, other: &dirent64) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && 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 PartialEq for pthread_rwlock_t {
-    fn eq(&self, other: &pthread_rwlock_t) -> bool {
-        self.size.iter().zip(other.size.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")
-            // FIXME: .field("size", &self.size)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for pthread_rwlock_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.size.hash(state);
+        impl Eq for dirent64 {}
+
+        impl ::fmt::Debug for dirent64 {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent64")
+                    .field("d_ino", &self.d_ino)
+                    .field("d_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for dirent64 {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_ino.hash(state);
+                self.d_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for pthread_cond_t {
+            fn eq(&self, other: &pthread_cond_t) -> bool {
+                self.size.iter().zip(other.size.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")
+                // FIXME: .field("size", &self.size)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for pthread_cond_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.size.hash(state);
+            }
+        }
+
+        impl PartialEq for pthread_mutex_t {
+            fn eq(&self, other: &pthread_mutex_t) -> bool {
+                self.size.iter().zip(other.size.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")
+                // FIXME: .field("size", &self.size)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for pthread_mutex_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.size.hash(state);
+            }
+        }
+
+        impl PartialEq for pthread_rwlock_t {
+            fn eq(&self, other: &pthread_rwlock_t) -> bool {
+                self.size.iter().zip(other.size.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")
+                // FIXME: .field("size", &self.size)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for pthread_rwlock_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.size.hash(state);
+            }
+        }
     }
 }
 
@@ -2502,3 +2357,14 @@ cfg_if! {
         pub use self::other::*;
     }
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        #[macro_use]
+        mod align;
+    } else {
+        #[macro_use]
+        mod no_align;
+    }
+}
+expand_align!();
diff --git a/src/unix/notbsd/linux/musl/b32/x86.rs b/src/unix/notbsd/linux/musl/b32/x86.rs
index 42ff2a2847e27da2b02ccf1fa603c8d235fd06fe..8bfb60ba3852aaf72cad272bb7fdf7a4b94e0e6a 100644
--- a/src/unix/notbsd/linux/musl/b32/x86.rs
+++ b/src/unix/notbsd/linux/musl/b32/x86.rs
@@ -177,45 +177,49 @@ s_no_extra_traits!{
         __private: [u8; 112],
     }
 }
-#[cfg(feature = "extra_traits")]
-impl PartialEq for ucontext_t {
-    fn eq(&self, other: &ucontext_t) -> bool {
-        self.uc_flags == other.uc_flags
-            && self.uc_link == other.uc_link
-            && self.uc_stack == other.uc_stack
-            && self.uc_mcontext == other.uc_mcontext
-            && self.uc_sigmask == other.uc_sigmask
-            && self
-                .__private
-                .iter()
-                .zip(other.__private.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for ucontext_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for ucontext_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("ucontext_t")
-            .field("uc_flags", &self.uc_flags)
-            .field("uc_link", &self.uc_link)
-            .field("uc_stack", &self.uc_stack)
-            .field("uc_mcontext", &self.uc_mcontext)
-            .field("uc_sigmask", &self.uc_sigmask)
-            // Ignore __private field
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for ucontext_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.uc_flags.hash(state);
-        self.uc_link.hash(state);
-        self.uc_stack.hash(state);
-        self.uc_mcontext.hash(state);
-        self.uc_sigmask.hash(state);
-        self.__private.hash(state);
+
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for ucontext_t {
+            fn eq(&self, other: &ucontext_t) -> bool {
+                self.uc_flags == other.uc_flags
+                    && self.uc_link == other.uc_link
+                    && self.uc_stack == other.uc_stack
+                    && self.uc_mcontext == other.uc_mcontext
+                    && self.uc_sigmask == other.uc_sigmask
+                    && self
+                    .__private
+                    .iter()
+                    .zip(other.__private.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for ucontext_t {}
+
+        impl ::fmt::Debug for ucontext_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("ucontext_t")
+                    .field("uc_flags", &self.uc_flags)
+                    .field("uc_link", &self.uc_link)
+                    .field("uc_stack", &self.uc_stack)
+                    .field("uc_mcontext", &self.uc_mcontext)
+                    .field("uc_sigmask", &self.uc_sigmask)
+                // Ignore __private field
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for ucontext_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.uc_flags.hash(state);
+                self.uc_link.hash(state);
+                self.uc_stack.hash(state);
+                self.uc_mcontext.hash(state);
+                self.uc_sigmask.hash(state);
+                self.__private.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/notbsd/linux/musl/b64/x86_64.rs b/src/unix/notbsd/linux/musl/b64/x86_64.rs
index 8462a4f635876d08b91591d49a407d37ffdb2dd6..94c5d88dab30611dc024d9ba6bb35610d800d88b 100644
--- a/src/unix/notbsd/linux/musl/b64/x86_64.rs
+++ b/src/unix/notbsd/linux/musl/b64/x86_64.rs
@@ -75,45 +75,48 @@ s_no_extra_traits!{
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for ucontext_t {
-    fn eq(&self, other: &ucontext_t) -> bool {
-        self.uc_flags == other.uc_flags
-            && self.uc_link == other.uc_link
-            && self.uc_stack == other.uc_stack
-            && self.uc_mcontext == other.uc_mcontext
-            && self.uc_sigmask == other.uc_sigmask
-            && self
-                .__private
-                .iter()
-                .zip(other.__private.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for ucontext_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for ucontext_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("ucontext_t")
-            .field("uc_flags", &self.uc_flags)
-            .field("uc_link", &self.uc_link)
-            .field("uc_stack", &self.uc_stack)
-            .field("uc_mcontext", &self.uc_mcontext)
-            .field("uc_sigmask", &self.uc_sigmask)
-            // Ignore __private field
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for ucontext_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.uc_flags.hash(state);
-        self.uc_link.hash(state);
-        self.uc_stack.hash(state);
-        self.uc_mcontext.hash(state);
-        self.uc_sigmask.hash(state);
-        self.__private.hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for ucontext_t {
+            fn eq(&self, other: &ucontext_t) -> bool {
+                self.uc_flags == other.uc_flags
+                    && self.uc_link == other.uc_link
+                    && self.uc_stack == other.uc_stack
+                    && self.uc_mcontext == other.uc_mcontext
+                    && self.uc_sigmask == other.uc_sigmask
+                    && self
+                    .__private
+                    .iter()
+                    .zip(other.__private.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for ucontext_t {}
+
+        impl ::fmt::Debug for ucontext_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("ucontext_t")
+                    .field("uc_flags", &self.uc_flags)
+                    .field("uc_link", &self.uc_link)
+                    .field("uc_stack", &self.uc_stack)
+                    .field("uc_mcontext", &self.uc_mcontext)
+                    .field("uc_sigmask", &self.uc_sigmask)
+                // Ignore __private field
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for ucontext_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.uc_flags.hash(state);
+                self.uc_link.hash(state);
+                self.uc_stack.hash(state);
+                self.uc_mcontext.hash(state);
+                self.uc_sigmask.hash(state);
+                self.__private.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/notbsd/linux/musl/mod.rs b/src/unix/notbsd/linux/musl/mod.rs
index b3ab650277187dfae14603f027834d7888b6dbe6..d5351d624bea6fd358e3799539f78b14f700d02c 100644
--- a/src/unix/notbsd/linux/musl/mod.rs
+++ b/src/unix/notbsd/linux/musl/mod.rs
@@ -99,65 +99,68 @@ s_no_extra_traits!{
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for sysinfo {
-    fn eq(&self, other: &sysinfo) -> bool {
-        self.uptime == other.uptime
-            && self.loads == other.loads
-            && self.totalram == other.totalram
-            && self.freeram == other.freeram
-            && self.sharedram == other.sharedram
-            && self.bufferram == other.bufferram
-            && self.totalswap == other.totalswap
-            && self.freeswap == other.freeswap
-            && self.procs == other.procs
-            && self.pad == other.pad
-            && self.totalhigh == other.totalhigh
-            && self.freehigh == other.freehigh
-            && self.mem_unit == other.mem_unit
-            // Ignore __reserved field
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for sysinfo {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for sysinfo {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("sysinfo")
-            .field("uptime", &self.uptime)
-            .field("loads", &self.loads)
-            .field("totalram", &self.totalram)
-            .field("freeram", &self.freeram)
-            .field("sharedram", &self.sharedram)
-            .field("bufferram", &self.bufferram)
-            .field("totalswap", &self.totalswap)
-            .field("freeswap", &self.freeswap)
-            .field("procs", &self.procs)
-            .field("pad", &self.pad)
-            .field("totalhigh", &self.totalhigh)
-            .field("freehigh", &self.freehigh)
-            .field("mem_unit", &self.mem_unit)
-            // FIXME: .field("__reserved", &self.__reserved)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for sysinfo {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.uptime.hash(state);
-        self.loads.hash(state);
-        self.totalram.hash(state);
-        self.freeram.hash(state);
-        self.sharedram.hash(state);
-        self.bufferram.hash(state);
-        self.totalswap.hash(state);
-        self.freeswap.hash(state);
-        self.procs.hash(state);
-        self.pad.hash(state);
-        self.totalhigh.hash(state);
-        self.freehigh.hash(state);
-        self.mem_unit.hash(state);
-        self.__reserved.hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for sysinfo {
+            fn eq(&self, other: &sysinfo) -> bool {
+                self.uptime == other.uptime
+                    && self.loads == other.loads
+                    && self.totalram == other.totalram
+                    && self.freeram == other.freeram
+                    && self.sharedram == other.sharedram
+                    && self.bufferram == other.bufferram
+                    && self.totalswap == other.totalswap
+                    && self.freeswap == other.freeswap
+                    && self.procs == other.procs
+                    && self.pad == other.pad
+                    && self.totalhigh == other.totalhigh
+                    && self.freehigh == other.freehigh
+                    && self.mem_unit == other.mem_unit
+                // Ignore __reserved field
+            }
+        }
+
+        impl Eq for sysinfo {}
+
+        impl ::fmt::Debug for sysinfo {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sysinfo")
+                    .field("uptime", &self.uptime)
+                    .field("loads", &self.loads)
+                    .field("totalram", &self.totalram)
+                    .field("freeram", &self.freeram)
+                    .field("sharedram", &self.sharedram)
+                    .field("bufferram", &self.bufferram)
+                    .field("totalswap", &self.totalswap)
+                    .field("freeswap", &self.freeswap)
+                    .field("procs", &self.procs)
+                    .field("pad", &self.pad)
+                    .field("totalhigh", &self.totalhigh)
+                    .field("freehigh", &self.freehigh)
+                    .field("mem_unit", &self.mem_unit)
+                // FIXME: .field("__reserved", &self.__reserved)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for sysinfo {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.uptime.hash(state);
+                self.loads.hash(state);
+                self.totalram.hash(state);
+                self.freeram.hash(state);
+                self.sharedram.hash(state);
+                self.bufferram.hash(state);
+                self.totalswap.hash(state);
+                self.freeswap.hash(state);
+                self.procs.hash(state);
+                self.pad.hash(state);
+                self.totalhigh.hash(state);
+                self.freehigh.hash(state);
+                self.mem_unit.hash(state);
+                self.__reserved.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/notbsd/linux/no_align.rs b/src/unix/notbsd/linux/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..1f5f2eea5706d5718634df3f8ca1b792f617b579
--- /dev/null
+++ b/src/unix/notbsd/linux/no_align.rs
@@ -0,0 +1,80 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            pub struct pthread_mutexattr_t {
+                #[cfg(any(target_arch = "x86_64",
+                          target_arch = "powerpc64",
+                          target_arch = "mips64",
+                          target_arch = "s390x",
+                          target_arch = "sparc64",
+                          all(target_arch = "aarch64",
+                              target_env = "musl")))]
+                __align: [::c_int; 0],
+                #[cfg(not(any(target_arch = "x86_64",
+                              target_arch = "powerpc64",
+                              target_arch = "mips64",
+                              target_arch = "s390x",
+                              target_arch = "sparc64",
+                              all(target_arch = "aarch64",
+                                  target_env = "musl"))))]
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            pub struct pthread_rwlockattr_t {
+                #[cfg(target_env = "musl")]
+                __align: [::c_int; 0],
+                #[cfg(not(target_env = "musl"))]
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T],
+            }
+
+            pub struct pthread_condattr_t {
+                __align: [::c_int; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+
+        s_no_extra_traits! {
+            pub struct pthread_cond_t {
+                #[cfg(target_env = "musl")]
+                __align: [*const ::c_void; 0],
+                #[cfg(not(target_env = "musl"))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+
+            pub struct pthread_mutex_t {
+                #[cfg(any(target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc",
+                          all(target_arch = "x86_64",
+                              target_pointer_width = "32")))]
+                __align: [::c_long; 0],
+                #[cfg(not(any(target_arch = "mips",
+                              target_arch = "arm",
+                              target_arch = "powerpc",
+                              all(target_arch = "x86_64",
+                                  target_pointer_width = "32"))))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            pub struct pthread_rwlock_t {
+                #[cfg(any(target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc",
+                          all(target_arch = "x86_64",
+                              target_pointer_width = "32")))]
+                __align: [::c_long; 0],
+                #[cfg(not(any(target_arch = "mips",
+                              target_arch = "arm",
+                              target_arch = "powerpc",
+                              all(target_arch = "x86_64",
+                                  target_pointer_width = "32"))))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/notbsd/linux/other/align.rs b/src/unix/notbsd/linux/other/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4a0e07460ebb10fe101ee84406726a5a2ac065a1
--- /dev/null
+++ b/src/unix/notbsd/linux/other/align.rs
@@ -0,0 +1,13 @@
+s! {
+    // FIXME this is actually a union
+    #[cfg_attr(target_pointer_width = "32",
+               repr(align(4)))]
+    #[cfg_attr(target_pointer_width = "64",
+               repr(align(8)))]
+    pub struct sem_t {
+        #[cfg(target_pointer_width = "32")]
+        __size: [::c_char; 16],
+        #[cfg(target_pointer_width = "64")]
+        __size: [::c_char; 32],
+    }
+}
diff --git a/src/unix/notbsd/linux/other/b32/x86.rs b/src/unix/notbsd/linux/other/b32/x86.rs
index fb48982162a3463c9411b8123b5002431e6de615..563ac98ac333554638566862940cb66468ff9100 100644
--- a/src/unix/notbsd/linux/other/b32/x86.rs
+++ b/src/unix/notbsd/linux/other/b32/x86.rs
@@ -215,99 +215,102 @@ s_no_extra_traits!{
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for user_fpxregs_struct {
-    fn eq(&self, other: &user_fpxregs_struct) -> bool {
-        self.cwd == other.cwd
-            && self.swd == other.swd
-            && self.twd == other.twd
-            && self.fop == other.fop
-            && self.fip == other.fip
-            && self.fcs == other.fcs
-            && self.foo == other.foo
-            && self.fos == other.fos
-            && self.mxcsr == other.mxcsr
-            // Ignore __reserved field
-            && self.st_space == other.st_space
-            && self.xmm_space == other.xmm_space
-            // Ignore padding field
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for user_fpxregs_struct {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for user_fpxregs_struct {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("user_fpxregs_struct")
-            .field("cwd", &self.cwd)
-            .field("swd", &self.swd)
-            .field("twd", &self.twd)
-            .field("fop", &self.fop)
-            .field("fip", &self.fip)
-            .field("fcs", &self.fcs)
-            .field("foo", &self.foo)
-            .field("fos", &self.fos)
-            .field("mxcsr", &self.mxcsr)
-            // Ignore __reserved field
-            .field("st_space", &self.st_space)
-            .field("xmm_space", &self.xmm_space)
-            // Ignore padding field
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for user_fpxregs_struct {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.cwd.hash(state);
-        self.swd.hash(state);
-        self.twd.hash(state);
-        self.fop.hash(state);
-        self.fip.hash(state);
-        self.fcs.hash(state);
-        self.foo.hash(state);
-        self.fos.hash(state);
-        self.mxcsr.hash(state);
-        // Ignore __reserved field
-        self.st_space.hash(state);
-        self.xmm_space.hash(state);
-        // Ignore padding field
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl PartialEq for ucontext_t {
-    fn eq(&self, other: &ucontext_t) -> bool {
-        self.uc_flags == other.uc_flags
-            && self.uc_link == other.uc_link
-            && self.uc_stack == other.uc_stack
-            && self.uc_mcontext == other.uc_mcontext
-            && self.uc_sigmask == other.uc_sigmask
-            // Ignore __private field
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for ucontext_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for ucontext_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("ucontext_t")
-            .field("uc_flags", &self.uc_flags)
-            .field("uc_link", &self.uc_link)
-            .field("uc_stack", &self.uc_stack)
-            .field("uc_mcontext", &self.uc_mcontext)
-            .field("uc_sigmask", &self.uc_sigmask)
-            // Ignore __private field
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for ucontext_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.uc_flags.hash(state);
-        self.uc_link.hash(state);
-        self.uc_stack.hash(state);
-        self.uc_mcontext.hash(state);
-        self.uc_sigmask.hash(state);
-        // Ignore __private field
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for user_fpxregs_struct {
+            fn eq(&self, other: &user_fpxregs_struct) -> bool {
+                self.cwd == other.cwd
+                    && self.swd == other.swd
+                    && self.twd == other.twd
+                    && self.fop == other.fop
+                    && self.fip == other.fip
+                    && self.fcs == other.fcs
+                    && self.foo == other.foo
+                    && self.fos == other.fos
+                    && self.mxcsr == other.mxcsr
+                // Ignore __reserved field
+                    && self.st_space == other.st_space
+                    && self.xmm_space == other.xmm_space
+                // Ignore padding field
+            }
+        }
+
+        impl Eq for user_fpxregs_struct {}
+
+        impl ::fmt::Debug for user_fpxregs_struct {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("user_fpxregs_struct")
+                    .field("cwd", &self.cwd)
+                    .field("swd", &self.swd)
+                    .field("twd", &self.twd)
+                    .field("fop", &self.fop)
+                    .field("fip", &self.fip)
+                    .field("fcs", &self.fcs)
+                    .field("foo", &self.foo)
+                    .field("fos", &self.fos)
+                    .field("mxcsr", &self.mxcsr)
+                // Ignore __reserved field
+                    .field("st_space", &self.st_space)
+                    .field("xmm_space", &self.xmm_space)
+                // Ignore padding field
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for user_fpxregs_struct {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.cwd.hash(state);
+                self.swd.hash(state);
+                self.twd.hash(state);
+                self.fop.hash(state);
+                self.fip.hash(state);
+                self.fcs.hash(state);
+                self.foo.hash(state);
+                self.fos.hash(state);
+                self.mxcsr.hash(state);
+                // Ignore __reserved field
+                self.st_space.hash(state);
+                self.xmm_space.hash(state);
+                // Ignore padding field
+            }
+        }
+
+        impl PartialEq for ucontext_t {
+            fn eq(&self, other: &ucontext_t) -> bool {
+                self.uc_flags == other.uc_flags
+                    && self.uc_link == other.uc_link
+                    && self.uc_stack == other.uc_stack
+                    && self.uc_mcontext == other.uc_mcontext
+                    && self.uc_sigmask == other.uc_sigmask
+                // Ignore __private field
+            }
+        }
+
+        impl Eq for ucontext_t {}
+
+        impl ::fmt::Debug for ucontext_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("ucontext_t")
+                    .field("uc_flags", &self.uc_flags)
+                    .field("uc_link", &self.uc_link)
+                    .field("uc_stack", &self.uc_stack)
+                    .field("uc_mcontext", &self.uc_mcontext)
+                    .field("uc_sigmask", &self.uc_sigmask)
+                // Ignore __private field
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for ucontext_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.uc_flags.hash(state);
+                self.uc_link.hash(state);
+                self.uc_stack.hash(state);
+                self.uc_mcontext.hash(state);
+                self.uc_sigmask.hash(state);
+                // Ignore __private field
+            }
+        }
     }
 }
 
diff --git a/src/unix/notbsd/linux/other/b64/x86_64.rs b/src/unix/notbsd/linux/other/b64/x86_64.rs
index b2a67ee9aab79ad88410de2294245d4ac9540036..d4f4ffc4da3993a145eb9704f659596fae82b6b2 100644
--- a/src/unix/notbsd/linux/other/b64/x86_64.rs
+++ b/src/unix/notbsd/linux/other/b64/x86_64.rs
@@ -234,96 +234,98 @@ s_no_extra_traits! {
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for user_fpregs_struct {
-    fn eq(&self, other: &user_fpregs_struct) -> bool {
-        self.cwd == other.cwd
-            && self.swd == other.swd
-            && self.ftw == other.ftw
-            && self.fop == other.fop
-            && self.rip == other.rip
-            && self.rdp == other.rdp
-            && self.mxcsr == other.mxcsr
-            && self.mxcr_mask == other.mxcr_mask
-            && self.st_space == other.st_space
-            && self
-                .xmm_space
-                .iter()
-                .zip(other.xmm_space.iter())
-                .all(|(a,b)| a == b)
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for user_fpregs_struct {
+            fn eq(&self, other: &user_fpregs_struct) -> bool {
+                self.cwd == other.cwd
+                    && self.swd == other.swd
+                    && self.ftw == other.ftw
+                    && self.fop == other.fop
+                    && self.rip == other.rip
+                    && self.rdp == other.rdp
+                    && self.mxcsr == other.mxcsr
+                    && self.mxcr_mask == other.mxcr_mask
+                    && self.st_space == other.st_space
+                    && self
+                    .xmm_space
+                    .iter()
+                    .zip(other.xmm_space.iter())
+                    .all(|(a,b)| a == b)
                 // Ignore padding field
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for user_fpregs_struct {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for user_fpregs_struct {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("user_fpregs_struct")
-            .field("cwd", &self.cwd)
-            .field("ftw", &self.ftw)
-            .field("fop", &self.fop)
-            .field("rip", &self.rip)
-            .field("rdp", &self.rdp)
-            .field("mxcsr", &self.mxcsr)
-            .field("mxcr_mask", &self.mxcr_mask)
-            .field("st_space", &self.st_space)
-            // FIXME: .field("xmm_space", &self.xmm_space)
-            // Ignore padding field
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for user_fpregs_struct {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.cwd.hash(state);
-        self.ftw.hash(state);
-        self.fop.hash(state);
-        self.rip.hash(state);
-        self.rdp.hash(state);
-        self.mxcsr.hash(state);
-        self.mxcr_mask.hash(state);
-        self.st_space.hash(state);
-        self.xmm_space.hash(state);
-        // Ignore padding field
-    }
-}
-
-#[cfg(feature = "extra_traits")]
-impl PartialEq for ucontext_t {
-    fn eq(&self, other: &ucontext_t) -> bool {
-        self.uc_flags == other.uc_flags
-            && self.uc_link == other.uc_link
-            && self.uc_stack == other.uc_stack
-            && self.uc_mcontext == other.uc_mcontext
-            && self.uc_sigmask == other.uc_sigmask
-            // Ignore __private field
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for ucontext_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for ucontext_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("ucontext_t")
-            .field("uc_flags", &self.uc_flags)
-            .field("uc_link", &self.uc_link)
-            .field("uc_stack", &self.uc_stack)
-            .field("uc_mcontext", &self.uc_mcontext)
-            .field("uc_sigmask", &self.uc_sigmask)
-            // Ignore __private field
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for ucontext_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.uc_flags.hash(state);
-        self.uc_link.hash(state);
-        self.uc_stack.hash(state);
-        self.uc_mcontext.hash(state);
-        self.uc_sigmask.hash(state);
-        // Ignore __private field
+            }
+        }
+
+        impl Eq for user_fpregs_struct {}
+
+        impl ::fmt::Debug for user_fpregs_struct {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("user_fpregs_struct")
+                    .field("cwd", &self.cwd)
+                    .field("ftw", &self.ftw)
+                    .field("fop", &self.fop)
+                    .field("rip", &self.rip)
+                    .field("rdp", &self.rdp)
+                    .field("mxcsr", &self.mxcsr)
+                    .field("mxcr_mask", &self.mxcr_mask)
+                    .field("st_space", &self.st_space)
+                // FIXME: .field("xmm_space", &self.xmm_space)
+                // Ignore padding field
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for user_fpregs_struct {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.cwd.hash(state);
+                self.ftw.hash(state);
+                self.fop.hash(state);
+                self.rip.hash(state);
+                self.rdp.hash(state);
+                self.mxcsr.hash(state);
+                self.mxcr_mask.hash(state);
+                self.st_space.hash(state);
+                self.xmm_space.hash(state);
+                // Ignore padding field
+            }
+        }
+
+        impl PartialEq for ucontext_t {
+            fn eq(&self, other: &ucontext_t) -> bool {
+                self.uc_flags == other.uc_flags
+                    && self.uc_link == other.uc_link
+                    && self.uc_stack == other.uc_stack
+                    && self.uc_mcontext == other.uc_mcontext
+                    && self.uc_sigmask == other.uc_sigmask
+                // Ignore __private field
+            }
+        }
+
+        impl Eq for ucontext_t {}
+
+        impl ::fmt::Debug for ucontext_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("ucontext_t")
+                    .field("uc_flags", &self.uc_flags)
+                    .field("uc_link", &self.uc_link)
+                    .field("uc_stack", &self.uc_stack)
+                    .field("uc_mcontext", &self.uc_mcontext)
+                    .field("uc_sigmask", &self.uc_sigmask)
+                // Ignore __private field
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for ucontext_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.uc_flags.hash(state);
+                self.uc_link.hash(state);
+                self.uc_stack.hash(state);
+                self.uc_mcontext.hash(state);
+                self.uc_sigmask.hash(state);
+                // Ignore __private field
+            }
+        }
     }
 }
 
diff --git a/src/unix/notbsd/linux/other/mod.rs b/src/unix/notbsd/linux/other/mod.rs
index 4036ceab1d3468aa837fa0685d1270fde34a81ac..497ea6d70a93dc594ba814ffd5be91d717de270c 100644
--- a/src/unix/notbsd/linux/other/mod.rs
+++ b/src/unix/notbsd/linux/other/mod.rs
@@ -121,20 +121,6 @@ s! {
         pub l_pid: ::pid_t,
     }
 
-    // FIXME this is actually a union
-    #[cfg_attr(all(feature = "align", target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align", target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct sem_t {
-        #[cfg(target_pointer_width = "32")]
-        __size: [::c_char; 16],
-        #[cfg(target_pointer_width = "64")]
-        __size: [::c_char; 32],
-        #[cfg(not(feature = "align"))]
-        __align: [::c_long; 0],
-    }
-
     pub struct mallinfo {
         pub arena: ::c_int,
         pub ordblks: ::c_int,
@@ -246,60 +232,63 @@ s_no_extra_traits! {
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for utmpx {
-    fn eq(&self, other: &utmpx) -> bool {
-        self.ut_type == other.ut_type
-            && self.ut_pid == other.ut_pid
-            && self.ut_line == other.ut_line
-            && self.ut_id == other.ut_id
-            && self.ut_user == other.ut_user
-            && self
-                .ut_host
-                .iter()
-                .zip(other.ut_host.iter())
-                .all(|(a,b)| a == b)
-            && self.ut_exit == other.ut_exit
-            && self.ut_session == other.ut_session
-            && self.ut_tv == other.ut_tv
-            && self.ut_addr_v6 == other.ut_addr_v6
-            && self.__glibc_reserved == other.__glibc_reserved
-    }
-}
-#[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")
-            .field("ut_type", &self.ut_type)
-            .field("ut_pid", &self.ut_pid)
-            .field("ut_line", &self.ut_line)
-            .field("ut_id", &self.ut_id)
-            .field("ut_user", &self.ut_user)
-            // FIXME: .field("ut_host", &self.ut_host)
-            .field("ut_exit", &self.ut_exit)
-            .field("ut_session", &self.ut_session)
-            .field("ut_tv", &self.ut_tv)
-            .field("ut_addr_v6", &self.ut_addr_v6)
-            .field("__glibc_reserved", &self.__glibc_reserved)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for utmpx {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.ut_type.hash(state);
-        self.ut_pid.hash(state);
-        self.ut_line.hash(state);
-        self.ut_id.hash(state);
-        self.ut_user.hash(state);
-        self.ut_host.hash(state);
-        self.ut_exit.hash(state);
-        self.ut_session.hash(state);
-        self.ut_tv.hash(state);
-        self.ut_addr_v6.hash(state);
-        self.__glibc_reserved.hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for utmpx {
+            fn eq(&self, other: &utmpx) -> bool {
+                self.ut_type == other.ut_type
+                    && self.ut_pid == other.ut_pid
+                    && self.ut_line == other.ut_line
+                    && self.ut_id == other.ut_id
+                    && self.ut_user == other.ut_user
+                    && self
+                    .ut_host
+                    .iter()
+                    .zip(other.ut_host.iter())
+                    .all(|(a,b)| a == b)
+                    && self.ut_exit == other.ut_exit
+                    && self.ut_session == other.ut_session
+                    && self.ut_tv == other.ut_tv
+                    && self.ut_addr_v6 == other.ut_addr_v6
+                    && self.__glibc_reserved == other.__glibc_reserved
+            }
+        }
+
+        impl Eq for utmpx {}
+
+        impl ::fmt::Debug for utmpx {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utmpx")
+                    .field("ut_type", &self.ut_type)
+                    .field("ut_pid", &self.ut_pid)
+                    .field("ut_line", &self.ut_line)
+                    .field("ut_id", &self.ut_id)
+                    .field("ut_user", &self.ut_user)
+                // FIXME: .field("ut_host", &self.ut_host)
+                    .field("ut_exit", &self.ut_exit)
+                    .field("ut_session", &self.ut_session)
+                    .field("ut_tv", &self.ut_tv)
+                    .field("ut_addr_v6", &self.ut_addr_v6)
+                    .field("__glibc_reserved", &self.__glibc_reserved)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for utmpx {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ut_type.hash(state);
+                self.ut_pid.hash(state);
+                self.ut_line.hash(state);
+                self.ut_id.hash(state);
+                self.ut_user.hash(state);
+                self.ut_host.hash(state);
+                self.ut_exit.hash(state);
+                self.ut_session.hash(state);
+                self.ut_tv.hash(state);
+                self.ut_addr_v6.hash(state);
+                self.__glibc_reserved.hash(state);
+            }
+        }
     }
 }
 
@@ -998,3 +987,13 @@ cfg_if! {
         // Unknown target_arch
     }
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        mod align;
+        pub use self::align::*;
+    } else {
+        mod no_align;
+        pub use self::no_align::*;
+    }
+}
diff --git a/src/unix/notbsd/linux/other/no_align.rs b/src/unix/notbsd/linux/other/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e32bf673d140e27b412196ccc9b9554b594e2ea8
--- /dev/null
+++ b/src/unix/notbsd/linux/other/no_align.rs
@@ -0,0 +1,10 @@
+s! {
+    // FIXME this is actually a union
+    pub struct sem_t {
+        #[cfg(target_pointer_width = "32")]
+        __size: [::c_char; 16],
+        #[cfg(target_pointer_width = "64")]
+        __size: [::c_char; 32],
+        __align: [::c_long; 0],
+    }
+}
diff --git a/src/unix/notbsd/linux/s390x/align.rs b/src/unix/notbsd/linux/s390x/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..21e21907d4a70f03de850a8d11f4c093aab1d622
--- /dev/null
+++ b/src/unix/notbsd/linux/s390x/align.rs
@@ -0,0 +1,10 @@
+s! {
+    // FIXME this is actually a union
+    #[cfg_attr(target_pointer_width = "32",
+               repr(align(4)))]
+    #[cfg_attr(target_pointer_width = "64",
+               repr(align(8)))]
+    pub struct sem_t {
+        __size: [::c_char; 32],
+    }
+}
diff --git a/src/unix/notbsd/linux/s390x.rs b/src/unix/notbsd/linux/s390x/mod.rs
similarity index 98%
rename from src/unix/notbsd/linux/s390x.rs
rename to src/unix/notbsd/linux/s390x/mod.rs
index f53e47e097cd0c0ef88c3198a437c90a39609e15..d4bc9bd2f4a102267d60b49dcd379bae162c89b2 100644
--- a/src/unix/notbsd/linux/s390x.rs
+++ b/src/unix/notbsd/linux/s390x/mod.rs
@@ -246,17 +246,6 @@ s! {
         pub l_pid: ::pid_t,
     }
 
-    // FIXME this is actually a union
-    #[cfg_attr(all(feature = "align", target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align", target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct sem_t {
-        __size: [::c_char; 32],
-        #[cfg(not(feature = "align"))]
-        __align: [::c_long; 0],
-    }
-
     pub struct __psw_t {
         pub mask: u64,
         pub addr: u64,
@@ -336,26 +325,30 @@ s_no_extra_traits!{
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for fpreg_t {
-    fn eq(&self, other: &fpreg_t) -> bool {
-        self.d == other.d
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for fpreg_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for fpreg_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("fpreg_t")
-            .field("d", &self.d)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for fpreg_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.d.to_bits().hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for fpreg_t {
+            fn eq(&self, other: &fpreg_t) -> bool {
+                self.d == other.d
+            }
+        }
+
+        impl Eq for fpreg_t {}
+
+        impl ::fmt::Debug for fpreg_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("fpreg_t")
+                    .field("d", &self.d)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for fpreg_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                let d: u64 = unsafe { ::mem::transmute(self.d) };
+                d.hash(state);
+            }
+        }
     }
 }
 
@@ -1359,3 +1352,13 @@ extern {
     pub fn swapcontext(uocp: *mut ucontext_t,
                        ucp: *const ucontext_t) -> ::c_int;
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        mod align;
+        pub use self::align::*;
+    } else {
+        mod no_align;
+        pub use self::no_align::*;
+    }
+}
diff --git a/src/unix/notbsd/linux/s390x/no_align.rs b/src/unix/notbsd/linux/s390x/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8909114cdfa42f6063b2423ce0d7a53d0a943c29
--- /dev/null
+++ b/src/unix/notbsd/linux/s390x/no_align.rs
@@ -0,0 +1,7 @@
+s! {
+    // FIXME this is actually a union
+    pub struct sem_t {
+        __size: [::c_char; 32],
+        __align: [::c_long; 0],
+    }
+}
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index 3698590ad452584281e0317b68fdcaea64eeede6..baabd6e84dadda46684f0bfea9ac523549e20293 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -16,6 +16,15 @@ impl ::dox::Clone for timezone {
 }
 
 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 sockaddr {
         pub sa_family: sa_family_t,
         pub sa_data: [::c_char; 14],
@@ -109,16 +118,6 @@ s! {
         pub dli_saddr: *mut ::c_void,
     }
 
-    #[cfg_attr(any(all(target_arch = "x86",
-                       not(target_env = "musl"),
-                       not(target_os = "android")),
-                   target_arch = "x86_64"),
-               repr(packed))]
-    pub struct epoll_event {
-        pub events: ::uint32_t,
-        pub u64: ::uint64_t,
-    }
-
     pub struct lconv {
         pub decimal_point: *mut ::c_char,
         pub thousands_sep: *mut ::c_char,
@@ -213,6 +212,20 @@ s! {
 }
 
 s_no_extra_traits!{
+    #[cfg_attr(
+        any(
+            all(
+                target_arch = "x86",
+                not(target_env = "musl"),
+                not(target_os = "android")),
+            target_arch = "x86_64"),
+        repr(packed))]
+    #[allow(missing_debug_implementations)]
+    pub struct epoll_event {
+        pub events: ::uint32_t,
+        pub u64: ::uint64_t,
+    }
+
     pub struct sockaddr_un {
         pub sun_family: sa_family_t,
         pub sun_path: [::c_char; 108]
@@ -237,125 +250,126 @@ s_no_extra_traits!{
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for sockaddr_un {
-    fn eq(&self, other: &sockaddr_un) -> bool {
-        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_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_family.hash(state);
-        self.sun_path.hash(state);
-    }
-}
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for sockaddr_un {
+            fn eq(&self, other: &sockaddr_un) -> bool {
+                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 PartialEq for sockaddr_storage {
-    fn eq(&self, other: &sockaddr_storage) -> bool {
-        self.ss_family == other.ss_family
-            && 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_family", &self.ss_family)
-            .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_family.hash(state);
-        self.__ss_pad2.hash(state);
-    }
-}
+        impl Eq for sockaddr_un {}
 
-#[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)
-            && self
-                .domainname
-                .iter()
-                .zip(other.domainname.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)
-            // FIXME: .field("domainname", &self.domainname)
-            .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);
-        self.domainname.hash(state);
+        impl ::fmt::Debug for sockaddr_un {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_un")
+                    .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_family.hash(state);
+                self.sun_path.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_storage {
+            fn eq(&self, other: &sockaddr_storage) -> bool {
+                self.ss_family == other.ss_family
+                    && 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_family", &self.ss_family)
+                    .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_family.hash(state);
+                self.__ss_pad2.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)
+                    && self
+                    .domainname
+                    .iter()
+                    .zip(other.domainname.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)
+                // FIXME: .field("domainname", &self.domainname)
+                    .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);
+                self.domainname.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/solaris/mod.rs b/src/unix/solaris/mod.rs
index c9a53e1f577377333d5166cff9bf41a42cc9028b..fce314f67074d6367c83d02964b856dbaf328797 100644
--- a/src/unix/solaris/mod.rs
+++ b/src/unix/solaris/mod.rs
@@ -44,6 +44,15 @@ impl ::dox::Clone for timezone {
 }
 
 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 sockaddr {
         pub sa_family: sa_family_t,
         pub sa_data: [::c_char; 14],
@@ -65,11 +74,6 @@ s! {
         pub __sin6_src_id: u32
     }
 
-    pub struct sockaddr_un {
-        pub sun_family: sa_family_t,
-        pub sun_path: [c_char; 108]
-    }
-
     pub struct passwd {
         pub pw_name: *mut ::c_char,
         pub pw_passwd: *mut ::c_char,
@@ -104,15 +108,7 @@ s! {
         pub tm_isdst: ::c_int
     }
 
-    pub struct utsname {
-        pub sysname: [::c_char; 257],
-        pub nodename: [::c_char; 257],
-        pub release: [::c_char; 257],
-        pub version: [::c_char; 257],
-        pub machine: [::c_char; 257],
-    }
-
-    pub struct msghdr {
+     pub struct msghdr {
         pub msg_name: *mut ::c_void,
         pub msg_namelen: ::socklen_t,
         pub msg_iov: *mut ::iovec,
@@ -128,13 +124,6 @@ s! {
         pub cmsg_type: ::c_int,
     }
 
-    pub struct fd_set {
-        #[cfg(target_pointer_width = "64")]
-        fds_bits: [i64; FD_SETSIZE / 64],
-        #[cfg(target_pointer_width = "32")]
-        fds_bits: [i32; FD_SETSIZE / 32],
-    }
-
     pub struct pthread_attr_t {
         __pthread_attrp: *mut ::c_void
     }
@@ -200,13 +189,6 @@ s! {
         __unused10: *mut ::c_void,
     }
 
-    pub struct sockaddr_storage {
-        pub ss_family: ::sa_family_t,
-        __ss_pad1: [u8; 6],
-        __ss_align: i64,
-        __ss_pad2: [u8; 240],
-    }
-
     pub struct addrinfo {
         pub ai_flags: ::c_int,
         pub ai_family: ::c_int,
@@ -224,15 +206,6 @@ s! {
         bits: [u32; 4],
     }
 
-    pub struct siginfo_t {
-        pub si_signo: ::c_int,
-        pub si_code: ::c_int,
-        pub si_errno: ::c_int,
-        pub si_pad: ::c_int,
-        pub si_addr: *mut ::c_void,
-        __pad: [u8; 232],
-    }
-
     pub struct sigaction {
         pub sa_flags: ::c_int,
         pub sa_sigaction: ::sighandler_t,
@@ -358,12 +331,56 @@ s! {
         pub portev_object: ::uintptr_t,
         pub portev_user: *mut ::c_void,
     }
+}
 
+s_no_extra_traits! {
     #[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), repr(packed))]
+    #[allow(missing_debug_implementations)]
     pub struct epoll_event {
         pub events: ::uint32_t,
         pub u64: ::uint64_t,
     }
+
+    #[allow(missing_debug_implementations)]
+    pub struct sockaddr_un {
+        pub sun_family: sa_family_t,
+        pub sun_path: [c_char; 108]
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct utsname {
+        pub sysname: [::c_char; 257],
+        pub nodename: [::c_char; 257],
+        pub release: [::c_char; 257],
+        pub version: [::c_char; 257],
+        pub machine: [::c_char; 257],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct fd_set {
+        #[cfg(target_pointer_width = "64")]
+        fds_bits: [i64; FD_SETSIZE / 64],
+        #[cfg(target_pointer_width = "32")]
+        fds_bits: [i32; FD_SETSIZE / 32],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct sockaddr_storage {
+        pub ss_family: ::sa_family_t,
+        __ss_pad1: [u8; 6],
+        __ss_align: i64,
+        __ss_pad2: [u8; 240],
+    }
+
+    #[allow(missing_debug_implementations)]
+    pub struct siginfo_t {
+        pub si_signo: ::c_int,
+        pub si_code: ::c_int,
+        pub si_errno: ::c_int,
+        pub si_pad: ::c_int,
+        pub si_addr: *mut ::c_void,
+        __pad: [u8; 232],
+    }
 }
 
 pub const LC_CTYPE: ::c_int = 0;
diff --git a/src/unix/uclibc/align.rs b/src/unix/uclibc/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..bcae2e6b0b7f8456a2d8d775acf954affac24865
--- /dev/null
+++ b/src/unix/uclibc/align.rs
@@ -0,0 +1,61 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "mips",
+                               target_arch = "arm",
+                               target_arch = "powerpc")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "mips",
+                                   target_arch = "arm",
+                                   target_arch = "powerpc"))),
+                       repr(align(8)))]
+            pub struct pthread_mutex_t {
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "mips",
+                               target_arch = "arm",
+                               target_arch = "powerpc")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "mips",
+                                   target_arch = "arm",
+                                   target_arch = "powerpc"))),
+                       repr(align(8)))]
+            pub struct pthread_rwlock_t {
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+
+            #[cfg_attr(any(target_pointer_width = "32",
+                           target_arch = "x86_64",
+                           target_arch = "powerpc64",
+                           target_arch = "mips64",
+                           target_arch = "s390x",
+                           target_arch = "sparc64"),
+                       repr(align(4)))]
+            #[cfg_attr(not(any(target_pointer_width = "32",
+                               target_arch = "x86_64",
+                               target_arch = "powerpc64",
+                               target_arch = "mips64",
+                               target_arch = "s390x",
+                               target_arch = "sparc64")),
+                       repr(align(8)))]
+            pub struct pthread_mutexattr_t {
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            #[repr(align(8))]
+            pub struct pthread_cond_t {
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_condattr_t {
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/uclibc/mips/mips32/align.rs b/src/unix/uclibc/mips/mips32/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..965c9c3cc44981c627e95456dd20c3d290fffcb6
--- /dev/null
+++ b/src/unix/uclibc/mips/mips32/align.rs
@@ -0,0 +1,13 @@
+s! {
+    // FIXME this is actually a union
+    #[cfg_attr(arget_pointer_width = "32",
+               repr(align(4)))]
+    #[cfg_attr(target_pointer_width = "64",
+               repr(align(8)))]
+    pub struct sem_t {
+        #[cfg(target_pointer_width = "32")]
+        __size: [::c_char; 16],
+        #[cfg(target_pointer_width = "64")]
+        __size: [::c_char; 32],
+    }
+}
diff --git a/src/unix/uclibc/mips/mips32.rs b/src/unix/uclibc/mips/mips32/mod.rs
similarity index 98%
rename from src/unix/uclibc/mips/mips32.rs
rename to src/unix/uclibc/mips/mips32/mod.rs
index dcbfcf8ff2bd2d88c1cbe58fe1aa1354b6c617a7..8dc9429e60c1c24e50ed7d9811cf007b51646e0f 100644
--- a/src/unix/uclibc/mips/mips32.rs
+++ b/src/unix/uclibc/mips/mips32/mod.rs
@@ -220,20 +220,6 @@ s! {
         pub mem_unit: ::c_uint,
         pub _f: [::c_char; 8],
     }
-
-    // FIXME this is actually a union
-    #[cfg_attr(all(feature = "align", target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align", target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct sem_t {
-        #[cfg(target_pointer_width = "32")]
-        __size: [::c_char; 16],
-        #[cfg(target_pointer_width = "64")]
-        __size: [::c_char; 32],
-        #[cfg(not(feature = "align"))]
-        __align: [::c_long; 0],
-    }
 }
 
 pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
@@ -637,3 +623,13 @@ extern {
                                        cpusetsize: ::size_t,
                                        cpuset: *const ::cpu_set_t) -> ::c_int;
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        mod align;
+        pub use self::align::*;
+    } else {
+        mod no_align;
+        pub use self::no_align::*;
+    }
+}
diff --git a/src/unix/uclibc/mips/mips32/no_align.rs b/src/unix/uclibc/mips/mips32/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e32bf673d140e27b412196ccc9b9554b594e2ea8
--- /dev/null
+++ b/src/unix/uclibc/mips/mips32/no_align.rs
@@ -0,0 +1,10 @@
+s! {
+    // FIXME this is actually a union
+    pub struct sem_t {
+        #[cfg(target_pointer_width = "32")]
+        __size: [::c_char; 16],
+        #[cfg(target_pointer_width = "64")]
+        __size: [::c_char; 32],
+        __align: [::c_long; 0],
+    }
+}
diff --git a/src/unix/uclibc/mips/mips64/align.rs b/src/unix/uclibc/mips/mips64/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..21e21907d4a70f03de850a8d11f4c093aab1d622
--- /dev/null
+++ b/src/unix/uclibc/mips/mips64/align.rs
@@ -0,0 +1,10 @@
+s! {
+    // FIXME this is actually a union
+    #[cfg_attr(target_pointer_width = "32",
+               repr(align(4)))]
+    #[cfg_attr(target_pointer_width = "64",
+               repr(align(8)))]
+    pub struct sem_t {
+        __size: [::c_char; 32],
+    }
+}
diff --git a/src/unix/uclibc/mips/mips64.rs b/src/unix/uclibc/mips/mips64/mod.rs
similarity index 93%
rename from src/unix/uclibc/mips/mips64.rs
rename to src/unix/uclibc/mips/mips64/mod.rs
index e35938b1fc8d983c5e02813c351aa1f52cd56a85..d80762e6c0acb71b9bb26a9ac5a2c69012205d04 100644
--- a/src/unix/uclibc/mips/mips64.rs
+++ b/src/unix/uclibc/mips/mips64/mod.rs
@@ -186,17 +186,6 @@ s! {
         pub mem_unit: ::c_uint,
         pub _f: [::c_char; 0],
     }
-
-    // FIXME this is actually a union
-    #[cfg_attr(all(feature = "align", target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align", target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct sem_t {
-        __size: [::c_char; 32],
-        #[cfg(not(feature = "align"))]
-        __align: [::c_long; 0],
-    }
 }
 
 pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
@@ -212,3 +201,13 @@ pub const SYS_gettid: ::c_long = 5178;   // Valid for n64
 extern {
     pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int;
 }
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        mod align;
+        pub use self::align::*;
+    } else {
+        mod no_align;
+        pub use self::no_align::*;
+    }
+}
diff --git a/src/unix/uclibc/mips/mips64/no_align.rs b/src/unix/uclibc/mips/mips64/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ee57ea88643db9981092a2b90d2246d440b9a3ec
--- /dev/null
+++ b/src/unix/uclibc/mips/mips64/no_align.rs
@@ -0,0 +1,8 @@
+s! {
+    // FIXME this is actually a union
+    pub struct sem_t {
+        __size: [::c_char; 32],
+        __align: [::c_long; 0],
+    }
+}
+
diff --git a/src/unix/uclibc/mod.rs b/src/unix/uclibc/mod.rs
index bb314196af60898cc2719451e4cbe5356eee185e..cfaef3bd736d8b138babc4ff33125f11e6ed6ad5 100644
--- a/src/unix/uclibc/mod.rs
+++ b/src/unix/uclibc/mod.rs
@@ -39,6 +39,15 @@ impl ::dox::Clone for timezone {
 }
 
 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 sockaddr {
         pub sa_family: sa_family_t,
         pub sa_data: [::c_char; 14],
@@ -133,14 +142,6 @@ s! {
         pub dli_saddr: *mut ::c_void,
     }
 
-    #[cfg_attr(any(all(target_arch = "x86",
-                   target_arch = "x86_64")),
-               repr(packed))]
-    pub struct epoll_event {
-        pub events: ::uint32_t,
-        pub u64: ::uint64_t,
-    }
-
     pub struct utsname {
         pub sysname: [::c_char; 65],
         pub nodename: [::c_char; 65],
@@ -234,103 +235,11 @@ s! {
         pub ifa_data: *mut ::c_void
     }
 
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "mips",
-                       target_arch = "arm",
-                       target_arch = "powerpc")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "mips",
-                               target_arch = "arm",
-                               target_arch = "powerpc")))),
-               repr(align(8)))]
-    pub struct pthread_mutex_t {
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "mips",
-                       target_arch = "arm",
-                       target_arch = "powerpc")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "mips",
-                               target_arch = "arm",
-                               target_arch = "powerpc")))),
-               repr(align(8)))]
-    pub struct pthread_rwlock_t {
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCK_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "32",
-                       target_arch = "x86_64", target_arch = "powerpc64",
-                       target_arch = "mips64", target_arch = "s390x",
-                       target_arch = "sparc64")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(any(target_pointer_width = "32",
-                           target_arch = "x86_64", target_arch = "powerpc64",
-                           target_arch = "mips64", target_arch = "s390x",
-                           target_arch = "sparc64"))),
-               repr(align(8)))]
-    pub struct pthread_mutexattr_t {
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "x86_64", target_arch = "powerpc64",
-                      target_arch = "mips64", target_arch = "s390x",
-                      target_arch = "sparc64")))]
-        __align: [::c_int; 0],
-        #[cfg(all(not(feature = "align"),
-                  not(any(target_arch = "x86_64", target_arch = "powerpc64",
-                          target_arch = "mips64", target_arch = "s390x",
-                          target_arch = "sparc64"))))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
-    }
-
     pub struct pthread_rwlockattr_t {
         __lockkind: ::c_int,
         __pshared: ::c_int,
     }
 
-    #[cfg_attr(feature = "align", repr(align(8)))]
-    pub struct pthread_cond_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_COND_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_condattr_t {
-        #[cfg(not(feature = "align"))]
-        __align: [::c_int; 0],
-        size: [u8; __SIZEOF_PTHREAD_CONDATTR_T],
-    }
-
     pub struct passwd {
         pub pw_name: *mut ::c_char,
         pub pw_passwd: *mut ::c_char,
@@ -446,6 +355,17 @@ s! {
     }
 }
 
+s_no_extra_traits! {
+    #[cfg_attr(
+        any(target_arch = "x86", target_arch = "x86_64"),
+        repr(packed)
+    )]
+    pub struct epoll_event {
+        pub events: ::uint32_t,
+        pub u64: ::uint64_t,
+    }
+}
+
 // intentionally not public, only used for fd_set
 cfg_if! {
     if #[cfg(target_pointer_width = "32")] {
@@ -1978,3 +1898,14 @@ cfg_if! {
     }
 }
 
+cfg_if! {
+    if #[cfg(libc_align)] {
+        #[macro_use]
+        mod align;
+    } else {
+        #[macro_use]
+        mod no_align;
+    }
+}
+
+expand_align!();
diff --git a/src/unix/uclibc/no_align.rs b/src/unix/uclibc/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a73dbded57ac710d2a78d6ee2cbd141147ae6352
--- /dev/null
+++ b/src/unix/uclibc/no_align.rs
@@ -0,0 +1,53 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            pub struct pthread_mutex_t {
+                #[cfg(any(target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc"))]
+                __align: [::c_long; 0],
+                #[cfg(any(libc_align,
+                          target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc"))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            pub struct pthread_rwlock_t {
+                #[cfg(any(target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc"))]
+                __align: [::c_long; 0],
+                #[cfg(not(any(
+                    target_arch = "mips",
+                    target_arch = "arm",
+                    target_arch = "powerpc")))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+
+            pub struct pthread_mutexattr_t {
+                #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64",
+                          target_arch = "mips64", target_arch = "s390x",
+                          target_arch = "sparc64"))]
+                __align: [::c_int; 0],
+                #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64",
+                              target_arch = "mips64", target_arch = "s390x",
+                              target_arch = "sparc64")))]
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            pub struct pthread_cond_t {
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+
+            pub struct pthread_condattr_t {
+                __align: [::c_int; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/uclibc/x86_64/align.rs b/src/unix/uclibc/x86_64/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..5fb4a4d5185efa2fbb6cc83defdeb72e4278cb38
--- /dev/null
+++ b/src/unix/uclibc/x86_64/align.rs
@@ -0,0 +1,72 @@
+macro_rules! expand_align {
+    () = > {
+        s! {
+            #[cfg_attr(target_pointer_width = "32",
+                       repr(align(4)))]
+            #[cfg_attr(target_pointer_width = "64",
+                       repr(align(8)))]
+            pub struct sem_t { // ToDo
+                #[cfg(target_pointer_width = "32")]
+                __size: [::c_char; 16],
+                #[cfg(target_pointer_width = "64")]
+                __size: [::c_char; 32],
+            }
+
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "mips",
+                               target_arch = "arm",
+                               target_arch = "powerpc")),
+                       repr(align(4)))]
+            #[cfg_attr(all(any(target_pointer_width = "64",
+                               not(any(target_arch = "mips",
+                                       target_arch = "arm",
+                                       target_arch = "powerpc")))),
+                       repr(align(8)))]
+            pub struct pthread_mutex_t { // ToDo
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            #[cfg_attr(any(target_pointer_width = "32",
+                           target_arch = "x86_64",
+                           target_arch = "powerpc64",
+                           target_arch = "mips64",
+                           target_arch = "s390x",
+                           target_arch = "sparc64"),
+                       repr(align(4)))]
+            #[cfg_attr(not(any(target_pointer_width = "32",
+                               target_arch = "x86_64",
+                               target_arch = "powerpc64",
+                               target_arch = "mips64",
+                               target_arch = "s390x",
+                               target_arch = "sparc64")),
+                       repr(align(8)))]
+            pub struct pthread_mutexattr_t { // ToDo
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            #[repr(align(8))]
+            pub struct pthread_cond_t { // ToDo
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+
+            #[repr(align(4))]
+            pub struct pthread_condattr_t { // ToDo
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+
+            #[cfg_attr(all(target_pointer_width = "32",
+                           any(target_arch = "mips",
+                               target_arch = "arm",
+                               target_arch = "powerpc")),
+                       repr(align(4)))]
+            #[cfg_attr(any(target_pointer_width = "64",
+                           not(any(target_arch = "mips",
+                                   target_arch = "arm",
+                                   target_arch = "powerpc"))),
+                       repr(align(8)))]
+            pub struct pthread_rwlock_t { // ToDo
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+        }
+    }
+}
diff --git a/src/unix/uclibc/x86_64/mod.rs b/src/unix/uclibc/x86_64/mod.rs
index bc6571aff98c22c3a5f790f8fa1246868e7f93e4..bc084394c3c54f07b818d439ab9d08a556a97f25 100644
--- a/src/unix/uclibc/x86_64/mod.rs
+++ b/src/unix/uclibc/x86_64/mod.rs
@@ -133,7 +133,7 @@ s! {
 //
 //    pub struct in6_addr {
 //        pub s6_addr: [u8; 16],
-//        #[cfg(not(feature = "align"))]
+//        #[cfg(not(libc_align))]
 //        __align: [u32; 0],
 //    }
 
@@ -205,111 +205,6 @@ s! {
         pub c_cc: [::cc_t; ::NCCS],
     }
 
-    #[cfg_attr(all(feature = "align", target_pointer_width = "32"),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align", target_pointer_width = "64"),
-               repr(align(8)))]
-    pub struct sem_t { // ToDo
-        #[cfg(target_pointer_width = "32")]
-        __size: [::c_char; 16],
-        #[cfg(target_pointer_width = "64")]
-        __size: [::c_char; 32],
-        #[cfg(not(feature = "align"))]
-        __align: [::c_long; 0],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "mips",
-                       target_arch = "arm",
-                       target_arch = "powerpc")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "mips",
-                               target_arch = "arm",
-                               target_arch = "powerpc")))),
-               repr(align(8)))]
-    pub struct pthread_mutex_t { // ToDo
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "32",
-                       target_arch = "x86_64", target_arch = "powerpc64",
-                       target_arch = "mips64", target_arch = "s390x",
-                       target_arch = "sparc64")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   not(any(target_pointer_width = "32",
-                           target_arch = "x86_64", target_arch = "powerpc64",
-                           target_arch = "mips64", target_arch = "s390x",
-                           target_arch = "sparc64"))),
-               repr(align(8)))]
-    pub struct pthread_mutexattr_t { // ToDo
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "x86_64", target_arch = "powerpc64",
-                      target_arch = "mips64", target_arch = "s390x",
-                      target_arch = "sparc64")))]
-        __align: [::c_int; 0],
-        #[cfg(all(not(feature = "align"),
-                  not(any(target_arch = "x86_64", target_arch = "powerpc64",
-                          target_arch = "mips64", target_arch = "s390x",
-                          target_arch = "sparc64"))))]
-        __align: [::c_long; 0],
-        size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(8)))]
-    pub struct pthread_cond_t { // ToDo
-        #[cfg(not(feature = "align"))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_COND_T],
-    }
-
-    #[cfg_attr(feature = "align", repr(align(4)))]
-    pub struct pthread_condattr_t { // ToDo
-        #[cfg(not(feature = "align"))]
-        __align: [::c_int; 0],
-        size: [u8; __SIZEOF_PTHREAD_CONDATTR_T],
-    }
-
-    #[cfg_attr(all(feature = "align",
-                   target_pointer_width = "32",
-                   any(target_arch = "mips",
-                       target_arch = "arm",
-                       target_arch = "powerpc")),
-               repr(align(4)))]
-    #[cfg_attr(all(feature = "align",
-                   any(target_pointer_width = "64",
-                       not(any(target_arch = "mips",
-                               target_arch = "arm",
-                               target_arch = "powerpc")))),
-               repr(align(8)))]
-    pub struct pthread_rwlock_t { // ToDo
-        #[cfg(all(not(feature = "align"),
-                  any(target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_long; 0],
-        #[cfg(not(any(feature = "align",
-                      target_arch = "mips",
-                      target_arch = "arm",
-                      target_arch = "powerpc")))]
-        __align: [::c_longlong; 0],
-        size: [u8; __SIZEOF_PTHREAD_RWLOCK_T],
-    }
-
     pub struct sigset_t { // ToDo
         __val: [::c_ulong; 16],
     }
@@ -414,3 +309,13 @@ cfg_if! {
     }
 }
 
+cfg_if! {
+    if #[cfg(libc_align)] {
+        #[macro_use]
+        mod align;
+    } else {
+        #[macro_use]
+        mod no_align;
+    }
+}
+expand_align!();
diff --git a/src/unix/uclibc/x86_64/no_align.rs b/src/unix/uclibc/x86_64/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..422d78fac25caec31a84677e36839c8b749cffbc
--- /dev/null
+++ b/src/unix/uclibc/x86_64/no_align.rs
@@ -0,0 +1,59 @@
+macro_rules! expand_align {
+    () => {
+        s! {
+            pub struct sem_t { // ToDo
+                #[cfg(target_pointer_width = "32")]
+                __size: [::c_char; 16],
+                #[cfg(target_pointer_width = "64")]
+                __size: [::c_char; 32],
+                __align: [::c_long; 0],
+            }
+
+            pub struct pthread_mutex_t { // ToDo
+                #[cfg(any(target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc"))]
+                __align: [::c_long; 0],
+                #[cfg(not(any(target_arch = "mips",
+                              target_arch = "arm",
+                              target_arch = "powerpc")))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
+            }
+
+            pub struct pthread_mutexattr_t { // ToDo
+                #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64",
+                          target_arch = "mips64", target_arch = "s390x",
+                          target_arch = "sparc64"))]
+                __align: [::c_int; 0],
+                #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64",
+                              target_arch = "mips64", target_arch = "s390x",
+                              target_arch = "sparc64")))]
+                __align: [::c_long; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T],
+            }
+
+            pub struct pthread_cond_t { // ToDo
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_COND_T],
+            }
+
+            pub struct pthread_condattr_t { // ToDo
+                __align: [::c_int; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T],
+            }
+
+            pub struct pthread_rwlock_t { // ToDo
+                #[cfg(any(target_arch = "mips",
+                          target_arch = "arm",
+                          target_arch = "powerpc"))]
+                __align: [::c_long; 0],
+                #[cfg(not(any(target_arch = "mips",
+                              target_arch = "arm",
+                              target_arch = "powerpc")))]
+                __align: [::c_longlong; 0],
+                size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
+            }
+        }
+    }
+}
diff --git a/src/windows/mod.rs b/src/windows/mod.rs
index 25a381ae72d27e824b4569a30917d0d7e39eebe9..acde2e9ee2261efa55e6ca9231cd27576f3c6a9d 100644
--- a/src/windows/mod.rs
+++ b/src/windows/mod.rs
@@ -434,14 +434,15 @@ extern "system" {
 }
 
 cfg_if! {
-    if #[cfg(core_cvoid)] {
-        pub use core::ffi::c_void;
+    if #[cfg(libc_core_cvoid)] {
+        pub use ::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)]
         #[allow(missing_copy_implementations)]
+        #[allow(missing_debug_implementations)]
         pub enum c_void {
             // Two dummy variants so the #[repr] attribute can be used.
             #[doc(hidden)]