blob: 508a3c82e15170ac384eb5b83e5fdcf053b97840 [file] [log] [blame]
Alex Crichtonb5da7c02015-09-16 17:44:40 -07001#![deny(warnings)]
2
Alex Crichtond11e9142015-09-15 23:28:52 -07003extern crate ctest;
Alex Crichton8e5f0cd2015-09-09 22:46:19 -07004
5use std::env;
Alex Crichton8e5f0cd2015-09-09 22:46:19 -07006
Alex Crichtond11e9142015-09-15 23:28:52 -07007fn main() {
8 let target = env::var("TARGET").unwrap();
9 let windows = target.contains("windows");
10 let mingw = target.contains("windows-gnu");
Alex Crichtoncd9b33e2015-09-17 14:47:40 -070011 let linux = target.contains("unknown-linux");
Alex Crichton1ff96102015-09-17 15:09:02 -070012 let android = target.contains("android");
Alex Crichtonbaef6112015-09-19 23:20:53 -070013 let apple = target.contains("apple");
Alex Crichton15b83c22015-09-17 17:25:52 -070014 let musl = target.contains("musl");
Alex Crichtona1b948e2015-09-18 11:54:32 -070015 let freebsd = target.contains("freebsd");
Alex Crichtonbaef6112015-09-19 23:20:53 -070016 let bsdlike = freebsd || apple;
Alex Crichtond11e9142015-09-15 23:28:52 -070017 let mut cfg = ctest::TestGenerator::new();
Alex Crichton8e5f0cd2015-09-09 22:46:19 -070018
Alex Crichtond11e9142015-09-15 23:28:52 -070019 // Pull in extra goodies on linux/mingw
Alex Crichton15b83c22015-09-17 17:25:52 -070020 if target.contains("unknown-linux") {
Alex Crichtond11e9142015-09-15 23:28:52 -070021 cfg.define("_GNU_SOURCE", None);
Alex Crichton1ff96102015-09-17 15:09:02 -070022 } else if windows {
Alex Crichtond11e9142015-09-15 23:28:52 -070023 cfg.define("_WIN32_WINNT", Some("0x8000"));
Alex Crichton0df7c102015-09-10 16:35:37 -070024 }
25
Alex Crichton094f44d2015-09-16 16:27:23 -070026 // Android doesn't actually have in_port_t but it's much easier if we
27 // provide one for us to test against
Alex Crichton1ff96102015-09-17 15:09:02 -070028 if android {
Alex Crichton094f44d2015-09-16 16:27:23 -070029 cfg.define("in_port_t", Some("uint16_t"));
30 }
31
Alex Crichtond11e9142015-09-15 23:28:52 -070032 cfg.header("errno.h")
33 .header("fcntl.h")
34 .header("limits.h")
35 .header("stddef.h")
36 .header("stdint.h")
37 .header("stdio.h")
38 .header("stdlib.h")
39 .header("sys/stat.h")
40 .header("sys/types.h")
41 .header("time.h")
42 .header("wchar.h");
Alex Crichtonac2bd852015-09-10 17:21:20 -070043
Alex Crichton1ff96102015-09-17 15:09:02 -070044 if windows {
Alex Crichtond11e9142015-09-15 23:28:52 -070045 cfg.header("winsock2.h"); // must be before windows.h
46
47 cfg.header("direct.h");
48 cfg.header("io.h");
49 cfg.header("sys/utime.h");
50 cfg.header("windows.h");
51 cfg.header("process.h");
52 cfg.header("ws2ipdef.h");
53
54 if target.contains("gnu") {
55 cfg.header("ws2tcpip.h");
Alex Crichton310d6232015-09-10 10:56:31 -070056 }
Alex Crichtond11e9142015-09-15 23:28:52 -070057 } else {
58 cfg.header("ctype.h");
59 cfg.header("dirent.h");
60 cfg.header("net/if.h");
61 cfg.header("netdb.h");
62 cfg.header("netinet/in.h");
63 cfg.header("netinet/ip.h");
64 cfg.header("netinet/tcp.h");
65 cfg.header("pthread.h");
Alex Crichton1ff96102015-09-17 15:09:02 -070066 cfg.header("dlfcn.h");
Alex Crichtond11e9142015-09-15 23:28:52 -070067 cfg.header("signal.h");
68 cfg.header("string.h");
69 cfg.header("sys/file.h");
70 cfg.header("sys/ioctl.h");
71 cfg.header("sys/mman.h");
72 cfg.header("sys/resource.h");
73 cfg.header("sys/socket.h");
74 cfg.header("sys/time.h");
75 cfg.header("sys/un.h");
76 cfg.header("sys/wait.h");
77 cfg.header("unistd.h");
78 cfg.header("utime.h");
Alex Crichtoncd9b33e2015-09-17 14:47:40 -070079 cfg.header("pwd.h");
80 cfg.header("grp.h");
Alex Crichtoncd9b33e2015-09-17 14:47:40 -070081 }
Alex Crichtona1b948e2015-09-18 11:54:32 -070082
83 if android {
84 cfg.header("arpa/inet.h");
Alex Crichton568705e2015-11-03 14:18:52 -080085 cfg.header("time64.h");
Alex Crichtona1b948e2015-09-18 11:54:32 -070086 } else if !windows {
87 cfg.header("glob.h");
88 cfg.header("ifaddrs.h");
Dan Burkert85a76f82015-11-04 20:26:27 -080089 cfg.header("sys/statvfs.h");
Alex Crichtona1b948e2015-09-18 11:54:32 -070090
91 if !musl {
92 cfg.header("execinfo.h");
93 cfg.header("sys/sysctl.h");
94 }
95 }
96
Alex Crichtonbaef6112015-09-19 23:20:53 -070097 if apple {
Alex Crichtona1b948e2015-09-18 11:54:32 -070098 cfg.header("mach-o/dyld.h");
99 cfg.header("mach/mach_time.h");
100 cfg.header("malloc/malloc.h");
Alex Crichtonbaef6112015-09-19 23:20:53 -0700101 if target.starts_with("x86") {
102 cfg.header("crt_externs.h");
103 }
Alex Crichtona1b948e2015-09-18 11:54:32 -0700104 }
105
106 if linux || android {
107 cfg.header("netpacket/packet.h");
108 cfg.header("net/ethernet.h");
109 cfg.header("malloc.h");
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700110 cfg.header("sys/prctl.h");
Alex Crichton310d6232015-09-10 10:56:31 -0700111 }
112
Alex Crichtona1b948e2015-09-18 11:54:32 -0700113 if freebsd {
114 cfg.header("pthread_np.h");
115 }
116
Alex Crichtond11e9142015-09-15 23:28:52 -0700117 cfg.type_name(move |ty, is_struct| {
Alex Crichton310d6232015-09-10 10:56:31 -0700118 match ty {
Alex Crichton31504842015-09-10 23:43:41 -0700119 // Just pass all these through, no need for a "struct" prefix
Alex Crichton22378822015-09-10 19:59:23 -0700120 "FILE" |
Alex Crichton07d3a0d2015-10-30 10:21:32 -0700121 "fd_set" |
Alex Crichton88d23e72015-11-02 17:03:19 -0800122 "Dl_info" |
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700123 "DIR" => ty.to_string(),
124
125 // Fixup a few types on windows that don't actually exist.
126 "time64_t" if windows => "__time64_t".to_string(),
127 "ssize_t" if windows => "SSIZE_T".to_string(),
128
Alex Crichtonde9736d2015-09-17 15:47:44 -0700129 // OSX calls this something else
Alex Crichtona1b948e2015-09-18 11:54:32 -0700130 "sighandler_t" if bsdlike => "sig_t".to_string(),
Alex Crichtonde9736d2015-09-17 15:47:44 -0700131
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700132 t if t.ends_with("_t") => t.to_string(),
Alex Crichton310d6232015-09-10 10:56:31 -0700133
Alex Crichton31504842015-09-10 23:43:41 -0700134 // Windows uppercase structs don't have `struct` in front, there's a
135 // few special cases for windows, and then otherwise put `struct` in
136 // front of everything.
Alex Crichtond11e9142015-09-15 23:28:52 -0700137 t if is_struct => {
Alex Crichton13a6f2d2015-09-10 18:10:58 -0700138 if windows && ty.chars().next().unwrap().is_uppercase() {
139 t.to_string()
140 } else if windows && t == "stat" {
141 "struct __stat64".to_string()
Alex Crichton7da9b102015-09-10 20:57:14 -0700142 } else if windows && t == "utimbuf" {
143 "struct __utimbuf64".to_string()
Alex Crichton13a6f2d2015-09-10 18:10:58 -0700144 } else {
145 format!("struct {}", t)
146 }
147 }
Alex Crichton310d6232015-09-10 10:56:31 -0700148
149 t => t.to_string(),
150 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700151 });
Alex Crichton310d6232015-09-10 10:56:31 -0700152
Alex Crichtond11e9142015-09-15 23:28:52 -0700153 let target2 = target.clone();
154 cfg.field_name(move |struct_, field| {
Alex Crichton310d6232015-09-10 10:56:31 -0700155 match field {
Alex Crichton31504842015-09-10 23:43:41 -0700156 // Our stat *_nsec fields normally don't actually exist but are part
157 // of a timeval struct
Alex Crichton74825222015-10-29 17:36:55 -0700158 s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
Alex Crichtonbaef6112015-09-19 23:20:53 -0700159 if target2.contains("apple") {
Alex Crichton310d6232015-09-10 10:56:31 -0700160 s.replace("_nsec", "spec.tv_nsec")
Alex Crichtond11e9142015-09-15 23:28:52 -0700161 } else if target2.contains("android") {
Alex Crichtond3d77922015-09-11 17:03:39 -0700162 s.to_string()
Alex Crichton310d6232015-09-10 10:56:31 -0700163 } else {
164 s.replace("e_nsec", ".tv_nsec")
165 }
166 }
167 s => s.to_string(),
168 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700169 });
Alex Crichton310d6232015-09-10 10:56:31 -0700170
Alex Crichtond11e9142015-09-15 23:28:52 -0700171 cfg.skip_type(move |ty| {
Alex Crichton310d6232015-09-10 10:56:31 -0700172 match ty {
Alex Crichtond3d77922015-09-11 17:03:39 -0700173 // sighandler_t is crazy across platforms
Alex Crichtond11e9142015-09-15 23:28:52 -0700174 "sighandler_t" => true,
Alex Crichtond3d77922015-09-11 17:03:39 -0700175
Alex Crichtond11e9142015-09-15 23:28:52 -0700176 _ => false
Alex Crichton310d6232015-09-10 10:56:31 -0700177 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700178 });
Alex Crichton16083062015-09-09 22:59:24 -0700179
Alex Crichtond11e9142015-09-15 23:28:52 -0700180 cfg.skip_signededness(|c| {
Alex Crichton6d3cfdb2015-09-15 14:53:01 -0700181 match c {
Alex Crichton7b28c272015-09-15 20:56:16 -0700182 "LARGE_INTEGER" |
Alex Crichtoneef03da2015-09-15 16:57:06 -0700183 "mach_timebase_info_data_t" |
Alex Crichton7b28c272015-09-15 20:56:16 -0700184 "float" |
Alex Crichtond11e9142015-09-15 23:28:52 -0700185 "double" => true,
186 n if n.starts_with("pthread") => true,
Alex Crichton18469182015-09-15 20:57:42 -0700187
188 // windows-isms
Alex Crichtond11e9142015-09-15 23:28:52 -0700189 n if n.starts_with("P") => true,
190 n if n.starts_with("H") => true,
191 n if n.starts_with("LP") => true,
192 _ => false,
Alex Crichton6d3cfdb2015-09-15 14:53:01 -0700193 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700194 });
Alex Crichton6d3cfdb2015-09-15 14:53:01 -0700195
Alex Crichtond11e9142015-09-15 23:28:52 -0700196 cfg.skip_const(move |name| {
Alex Crichton31504842015-09-10 23:43:41 -0700197 match name {
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700198 // Apparently these don't exist in mingw headers?
Alex Crichton31504842015-09-10 23:43:41 -0700199 "MEM_RESET_UNDO" |
200 "FILE_ATTRIBUTE_NO_SCRUB_DATA" |
201 "FILE_ATTRIBUTE_INTEGRITY_STREAM" |
Alex Crichtond11e9142015-09-15 23:28:52 -0700202 "ERROR_NOTHING_TO_TERMINATE" if mingw => true,
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700203
Alex Crichtond11e9142015-09-15 23:28:52 -0700204 "SIG_IGN" => true, // sighandler_t weirdness
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700205
Alex Crichton15b83c22015-09-17 17:25:52 -0700206 // types on musl are defined a little differently
Alex Crichton3a572fd2015-10-29 16:52:25 -0700207 n if musl && n.contains("__SIZEOF_PTHREAD") => true,
Alex Crichton15b83c22015-09-17 17:25:52 -0700208
Alex Crichton74825222015-10-29 17:36:55 -0700209 // Skip constants not defined in MUSL but just passed down to the
210 // kernel regardless
211 "RLIMIT_NLIMITS" |
212 "TCP_COOKIE_TRANSACTIONS" |
213 "RLIMIT_RTTIME" if musl => true,
214
Alex Crichtond11e9142015-09-15 23:28:52 -0700215 _ => false,
Alex Crichton31504842015-09-10 23:43:41 -0700216 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700217 });
Alex Crichton31504842015-09-10 23:43:41 -0700218
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700219 cfg.skip_fn(move |name| {
220 // skip those that are manually verifiedmanually verified
Alex Crichton22378822015-09-10 19:59:23 -0700221 match name {
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700222 "execv" | // crazy stuff with const/mut
Alex Crichton22378822015-09-10 19:59:23 -0700223 "execve" |
224 "execvp" |
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700225 "execvpe" => true,
226
Alex Crichton74825222015-10-29 17:36:55 -0700227 "getrlimit" | "getrlimit64" | // non-int in 1st arg
228 "setrlimit" | "setrlimit64" | // non-int in 1st arg
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700229 "strerror_r" if linux => true, // actually xpg-something-or-other
230
Alex Crichton1ff96102015-09-17 15:09:02 -0700231 // typed 2nd arg on linux and android
Alex Crichtona1b948e2015-09-18 11:54:32 -0700232 "gettimeofday" if linux || android || freebsd => true,
Alex Crichton1ff96102015-09-17 15:09:02 -0700233
234 "dlerror" if android => true, // const-ness is added
Alex Crichton88d23e72015-11-02 17:03:19 -0800235 "dladdr" if musl => true, // const-ness only added recently
Alex Crichton1ff96102015-09-17 15:09:02 -0700236
Alex Crichton568705e2015-11-03 14:18:52 -0800237 // OSX has 'struct tm *const' which we can't actually represent in
238 // Rust, but is close enough to *mut
239 "timegm" if apple => true,
240
Alex Crichtond11e9142015-09-15 23:28:52 -0700241 _ => false,
Alex Crichton22378822015-09-10 19:59:23 -0700242 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700243 });
Alex Crichton22378822015-09-10 19:59:23 -0700244
Alex Crichtone0f4d102015-09-16 09:48:14 -0700245 // Windows dllimport oddness?
246 cfg.skip_fn_ptrcheck(move |_| windows);
247
Alex Crichton15b83c22015-09-17 17:25:52 -0700248 cfg.skip_field_type(move |struct_, field| {
Alex Crichtonf3b97482015-09-16 14:13:20 -0700249 // This is a weird union, don't check the type.
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700250 (struct_ == "ifaddrs" && field == "ifa_ifu") ||
251 // sighandler_t type is super weird
252 (struct_ == "sigaction" && field == "sa_sigaction")
253 });
254
Alex Crichton15b83c22015-09-17 17:25:52 -0700255 cfg.skip_field(move |struct_, field| {
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700256 // this is actually a union on linux, so we can't represent it well and
257 // just insert some padding.
Alex Crichton15b83c22015-09-17 17:25:52 -0700258 (struct_ == "siginfo_t" && field == "_pad") ||
259 // musl names this __dummy1 but it's still there
260 (musl && struct_ == "glob_t" && field == "gl_flags")
Alex Crichtonf3b97482015-09-16 14:13:20 -0700261 });
262
Alex Crichtond11e9142015-09-15 23:28:52 -0700263 cfg.generate("../src/lib.rs", "all.rs");
Alex Crichton310d6232015-09-10 10:56:31 -0700264}