blob: ee68b64fd0f7eadd32d6242b4b9bc7e9fd17af07 [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");
85 } else if !windows {
86 cfg.header("glob.h");
87 cfg.header("ifaddrs.h");
88
89 if !musl {
90 cfg.header("execinfo.h");
91 cfg.header("sys/sysctl.h");
92 }
93 }
94
Alex Crichtonbaef6112015-09-19 23:20:53 -070095 if apple {
Alex Crichtona1b948e2015-09-18 11:54:32 -070096 cfg.header("mach-o/dyld.h");
97 cfg.header("mach/mach_time.h");
98 cfg.header("malloc/malloc.h");
Alex Crichtonbaef6112015-09-19 23:20:53 -070099 if target.starts_with("x86") {
100 cfg.header("crt_externs.h");
101 }
Alex Crichtona1b948e2015-09-18 11:54:32 -0700102 }
103
104 if linux || android {
105 cfg.header("netpacket/packet.h");
106 cfg.header("net/ethernet.h");
107 cfg.header("malloc.h");
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700108 cfg.header("sys/prctl.h");
Alex Crichton310d6232015-09-10 10:56:31 -0700109 }
110
Alex Crichtona1b948e2015-09-18 11:54:32 -0700111 if freebsd {
112 cfg.header("pthread_np.h");
113 }
114
Alex Crichtond11e9142015-09-15 23:28:52 -0700115 cfg.type_name(move |ty, is_struct| {
Alex Crichton310d6232015-09-10 10:56:31 -0700116 match ty {
Alex Crichton31504842015-09-10 23:43:41 -0700117 // Just pass all these through, no need for a "struct" prefix
Alex Crichton22378822015-09-10 19:59:23 -0700118 "FILE" |
Alex Crichton07d3a0d2015-10-30 10:21:32 -0700119 "fd_set" |
Alex Crichton88d23e72015-11-02 17:03:19 -0800120 "Dl_info" |
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700121 "DIR" => ty.to_string(),
122
123 // Fixup a few types on windows that don't actually exist.
124 "time64_t" if windows => "__time64_t".to_string(),
125 "ssize_t" if windows => "SSIZE_T".to_string(),
126
Alex Crichtonde9736d2015-09-17 15:47:44 -0700127 // OSX calls this something else
Alex Crichtona1b948e2015-09-18 11:54:32 -0700128 "sighandler_t" if bsdlike => "sig_t".to_string(),
Alex Crichtonde9736d2015-09-17 15:47:44 -0700129
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700130 t if t.ends_with("_t") => t.to_string(),
Alex Crichton310d6232015-09-10 10:56:31 -0700131
Alex Crichton31504842015-09-10 23:43:41 -0700132 // Windows uppercase structs don't have `struct` in front, there's a
133 // few special cases for windows, and then otherwise put `struct` in
134 // front of everything.
Alex Crichtond11e9142015-09-15 23:28:52 -0700135 t if is_struct => {
Alex Crichton13a6f2d2015-09-10 18:10:58 -0700136 if windows && ty.chars().next().unwrap().is_uppercase() {
137 t.to_string()
138 } else if windows && t == "stat" {
139 "struct __stat64".to_string()
Alex Crichton7da9b102015-09-10 20:57:14 -0700140 } else if windows && t == "utimbuf" {
141 "struct __utimbuf64".to_string()
Alex Crichton13a6f2d2015-09-10 18:10:58 -0700142 } else {
143 format!("struct {}", t)
144 }
145 }
Alex Crichton310d6232015-09-10 10:56:31 -0700146
147 t => t.to_string(),
148 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700149 });
Alex Crichton310d6232015-09-10 10:56:31 -0700150
Alex Crichtond11e9142015-09-15 23:28:52 -0700151 let target2 = target.clone();
152 cfg.field_name(move |struct_, field| {
Alex Crichton310d6232015-09-10 10:56:31 -0700153 match field {
Alex Crichton31504842015-09-10 23:43:41 -0700154 // Our stat *_nsec fields normally don't actually exist but are part
155 // of a timeval struct
Alex Crichton74825222015-10-29 17:36:55 -0700156 s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
Alex Crichtonbaef6112015-09-19 23:20:53 -0700157 if target2.contains("apple") {
Alex Crichton310d6232015-09-10 10:56:31 -0700158 s.replace("_nsec", "spec.tv_nsec")
Alex Crichtond11e9142015-09-15 23:28:52 -0700159 } else if target2.contains("android") {
Alex Crichtond3d77922015-09-11 17:03:39 -0700160 s.to_string()
Alex Crichton310d6232015-09-10 10:56:31 -0700161 } else {
162 s.replace("e_nsec", ".tv_nsec")
163 }
164 }
165 s => s.to_string(),
166 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700167 });
Alex Crichton310d6232015-09-10 10:56:31 -0700168
Alex Crichtond11e9142015-09-15 23:28:52 -0700169 cfg.skip_type(move |ty| {
Alex Crichton310d6232015-09-10 10:56:31 -0700170 match ty {
Alex Crichtond3d77922015-09-11 17:03:39 -0700171 // sighandler_t is crazy across platforms
Alex Crichtond11e9142015-09-15 23:28:52 -0700172 "sighandler_t" => true,
Alex Crichtond3d77922015-09-11 17:03:39 -0700173
Alex Crichtond11e9142015-09-15 23:28:52 -0700174 _ => false
Alex Crichton310d6232015-09-10 10:56:31 -0700175 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700176 });
Alex Crichton16083062015-09-09 22:59:24 -0700177
Alex Crichtond11e9142015-09-15 23:28:52 -0700178 cfg.skip_signededness(|c| {
Alex Crichton6d3cfdb2015-09-15 14:53:01 -0700179 match c {
Alex Crichton7b28c272015-09-15 20:56:16 -0700180 "LARGE_INTEGER" |
Alex Crichtoneef03da2015-09-15 16:57:06 -0700181 "mach_timebase_info_data_t" |
Alex Crichton7b28c272015-09-15 20:56:16 -0700182 "float" |
Alex Crichtond11e9142015-09-15 23:28:52 -0700183 "double" => true,
184 n if n.starts_with("pthread") => true,
Alex Crichton18469182015-09-15 20:57:42 -0700185
186 // windows-isms
Alex Crichtond11e9142015-09-15 23:28:52 -0700187 n if n.starts_with("P") => true,
188 n if n.starts_with("H") => true,
189 n if n.starts_with("LP") => true,
190 _ => false,
Alex Crichton6d3cfdb2015-09-15 14:53:01 -0700191 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700192 });
Alex Crichton6d3cfdb2015-09-15 14:53:01 -0700193
Alex Crichtond11e9142015-09-15 23:28:52 -0700194 cfg.skip_const(move |name| {
Alex Crichton31504842015-09-10 23:43:41 -0700195 match name {
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700196 // Apparently these don't exist in mingw headers?
Alex Crichton31504842015-09-10 23:43:41 -0700197 "MEM_RESET_UNDO" |
198 "FILE_ATTRIBUTE_NO_SCRUB_DATA" |
199 "FILE_ATTRIBUTE_INTEGRITY_STREAM" |
Alex Crichtond11e9142015-09-15 23:28:52 -0700200 "ERROR_NOTHING_TO_TERMINATE" if mingw => true,
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700201
Alex Crichtond11e9142015-09-15 23:28:52 -0700202 "SIG_IGN" => true, // sighandler_t weirdness
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700203
Alex Crichton15b83c22015-09-17 17:25:52 -0700204 // types on musl are defined a little differently
Alex Crichton3a572fd2015-10-29 16:52:25 -0700205 n if musl && n.contains("__SIZEOF_PTHREAD") => true,
Alex Crichton15b83c22015-09-17 17:25:52 -0700206
Alex Crichton74825222015-10-29 17:36:55 -0700207 // Skip constants not defined in MUSL but just passed down to the
208 // kernel regardless
209 "RLIMIT_NLIMITS" |
210 "TCP_COOKIE_TRANSACTIONS" |
211 "RLIMIT_RTTIME" if musl => true,
212
Alex Crichtond11e9142015-09-15 23:28:52 -0700213 _ => false,
Alex Crichton31504842015-09-10 23:43:41 -0700214 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700215 });
Alex Crichton31504842015-09-10 23:43:41 -0700216
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700217 cfg.skip_fn(move |name| {
218 // skip those that are manually verifiedmanually verified
Alex Crichton22378822015-09-10 19:59:23 -0700219 match name {
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700220 "execv" | // crazy stuff with const/mut
Alex Crichton22378822015-09-10 19:59:23 -0700221 "execve" |
222 "execvp" |
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700223 "execvpe" => true,
224
Alex Crichton74825222015-10-29 17:36:55 -0700225 "getrlimit" | "getrlimit64" | // non-int in 1st arg
226 "setrlimit" | "setrlimit64" | // non-int in 1st arg
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700227 "strerror_r" if linux => true, // actually xpg-something-or-other
228
Alex Crichton1ff96102015-09-17 15:09:02 -0700229 // typed 2nd arg on linux and android
Alex Crichtona1b948e2015-09-18 11:54:32 -0700230 "gettimeofday" if linux || android || freebsd => true,
Alex Crichton1ff96102015-09-17 15:09:02 -0700231
232 "dlerror" if android => true, // const-ness is added
Alex Crichton88d23e72015-11-02 17:03:19 -0800233 "dladdr" if musl => true, // const-ness only added recently
Alex Crichton1ff96102015-09-17 15:09:02 -0700234
Alex Crichtond11e9142015-09-15 23:28:52 -0700235 _ => false,
Alex Crichton22378822015-09-10 19:59:23 -0700236 }
Alex Crichtond11e9142015-09-15 23:28:52 -0700237 });
Alex Crichton22378822015-09-10 19:59:23 -0700238
Alex Crichtone0f4d102015-09-16 09:48:14 -0700239 // Windows dllimport oddness?
240 cfg.skip_fn_ptrcheck(move |_| windows);
241
Alex Crichton15b83c22015-09-17 17:25:52 -0700242 cfg.skip_field_type(move |struct_, field| {
Alex Crichtonf3b97482015-09-16 14:13:20 -0700243 // This is a weird union, don't check the type.
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700244 (struct_ == "ifaddrs" && field == "ifa_ifu") ||
245 // sighandler_t type is super weird
246 (struct_ == "sigaction" && field == "sa_sigaction")
247 });
248
Alex Crichton15b83c22015-09-17 17:25:52 -0700249 cfg.skip_field(move |struct_, field| {
Alex Crichtoncd9b33e2015-09-17 14:47:40 -0700250 // this is actually a union on linux, so we can't represent it well and
251 // just insert some padding.
Alex Crichton15b83c22015-09-17 17:25:52 -0700252 (struct_ == "siginfo_t" && field == "_pad") ||
253 // musl names this __dummy1 but it's still there
254 (musl && struct_ == "glob_t" && field == "gl_flags")
Alex Crichtonf3b97482015-09-16 14:13:20 -0700255 });
256
Alex Crichtond11e9142015-09-15 23:28:52 -0700257 cfg.generate("../src/lib.rs", "all.rs");
Alex Crichton310d6232015-09-10 10:56:31 -0700258}