]>
Commit | Line | Data |
---|---|---|
1 | #![deny(warnings)] | |
2 | ||
3 | extern crate ctest; | |
4 | ||
5 | use std::env; | |
6 | ||
7 | fn main() { | |
8 | let target = env::var("TARGET").unwrap(); | |
9 | let aarch64 = target.contains("aarch64"); | |
10 | let x86_64 = target.contains("x86_64"); | |
11 | let windows = target.contains("windows"); | |
12 | let mingw = target.contains("windows-gnu"); | |
13 | let linux = target.contains("unknown-linux"); | |
14 | let android = target.contains("android"); | |
15 | let apple = target.contains("apple"); | |
16 | let musl = target.contains("musl"); | |
17 | let uclibc = target.contains("uclibc"); | |
18 | let freebsd = target.contains("freebsd"); | |
19 | let dragonfly = target.contains("dragonfly"); | |
20 | let mips = target.contains("mips"); | |
21 | let netbsd = target.contains("netbsd"); | |
22 | let openbsd = target.contains("openbsd"); | |
23 | let rumprun = target.contains("rumprun"); | |
24 | let bsdlike = freebsd || apple || netbsd || openbsd || dragonfly; | |
25 | let mut cfg = ctest::TestGenerator::new(); | |
26 | ||
27 | // Pull in extra goodies | |
28 | if linux || android { | |
29 | cfg.define("_GNU_SOURCE", None); | |
30 | } else if netbsd { | |
31 | cfg.define("_NETBSD_SOURCE", Some("1")); | |
32 | } else if windows { | |
33 | cfg.define("_WIN32_WINNT", Some("0x8000")); | |
34 | } | |
35 | ||
36 | // Android doesn't actually have in_port_t but it's much easier if we | |
37 | // provide one for us to test against | |
38 | if android { | |
39 | cfg.define("in_port_t", Some("uint16_t")); | |
40 | } | |
41 | ||
42 | cfg.header("errno.h") | |
43 | .header("fcntl.h") | |
44 | .header("limits.h") | |
45 | .header("locale.h") | |
46 | .header("stddef.h") | |
47 | .header("stdint.h") | |
48 | .header("stdio.h") | |
49 | .header("stdlib.h") | |
50 | .header("sys/stat.h") | |
51 | .header("sys/types.h") | |
52 | .header("time.h") | |
53 | .header("wchar.h"); | |
54 | ||
55 | if windows { | |
56 | cfg.header("winsock2.h"); // must be before windows.h | |
57 | ||
58 | cfg.header("direct.h"); | |
59 | cfg.header("io.h"); | |
60 | cfg.header("sys/utime.h"); | |
61 | cfg.header("windows.h"); | |
62 | cfg.header("process.h"); | |
63 | cfg.header("ws2ipdef.h"); | |
64 | ||
65 | if target.contains("gnu") { | |
66 | cfg.header("ws2tcpip.h"); | |
67 | } | |
68 | } else { | |
69 | cfg.flag("-Wno-deprecated-declarations"); | |
70 | ||
71 | cfg.header("ctype.h"); | |
72 | cfg.header("dirent.h"); | |
73 | if openbsd { | |
74 | cfg.header("sys/socket.h"); | |
75 | } | |
76 | cfg.header("net/if.h"); | |
77 | cfg.header("netdb.h"); | |
78 | cfg.header("netinet/in.h"); | |
79 | cfg.header("netinet/ip.h"); | |
80 | cfg.header("netinet/tcp.h"); | |
81 | cfg.header("resolv.h"); | |
82 | cfg.header("pthread.h"); | |
83 | cfg.header("dlfcn.h"); | |
84 | cfg.header("signal.h"); | |
85 | cfg.header("string.h"); | |
86 | cfg.header("sys/file.h"); | |
87 | cfg.header("sys/ioctl.h"); | |
88 | cfg.header("sys/mman.h"); | |
89 | cfg.header("sys/resource.h"); | |
90 | cfg.header("sys/socket.h"); | |
91 | cfg.header("sys/time.h"); | |
92 | cfg.header("sys/un.h"); | |
93 | cfg.header("sys/wait.h"); | |
94 | cfg.header("unistd.h"); | |
95 | cfg.header("utime.h"); | |
96 | cfg.header("pwd.h"); | |
97 | cfg.header("grp.h"); | |
98 | cfg.header("sys/utsname.h"); | |
99 | cfg.header("sys/ptrace.h"); | |
100 | cfg.header("sys/mount.h"); | |
101 | cfg.header("sys/uio.h"); | |
102 | cfg.header("sched.h"); | |
103 | cfg.header("termios.h"); | |
104 | cfg.header("poll.h"); | |
105 | cfg.header("syslog.h"); | |
106 | cfg.header("semaphore.h"); | |
107 | cfg.header("sys/statvfs.h"); | |
108 | cfg.header("sys/times.h"); | |
109 | } | |
110 | ||
111 | if android { | |
112 | if !aarch64 && !x86_64 { | |
113 | // time64_t is not define for aarch64 and x86_64 | |
114 | // If included it will generate the error 'Your time_t is already 64-bit' | |
115 | cfg.header("time64.h"); | |
116 | } | |
117 | cfg.header("arpa/inet.h"); | |
118 | cfg.header("xlocale.h"); | |
119 | cfg.header("utmp.h"); | |
120 | } else if !windows { | |
121 | cfg.header("glob.h"); | |
122 | cfg.header("ifaddrs.h"); | |
123 | cfg.header("langinfo.h"); | |
124 | ||
125 | if !openbsd && !freebsd && !dragonfly { | |
126 | cfg.header("sys/quota.h"); | |
127 | } | |
128 | ||
129 | if !musl { | |
130 | cfg.header("sys/sysctl.h"); | |
131 | } | |
132 | if !musl && !uclibc { | |
133 | ||
134 | if !netbsd && !openbsd && !uclibc { | |
135 | cfg.header("execinfo.h"); | |
136 | cfg.header("xlocale.h"); | |
137 | } | |
138 | ||
139 | if openbsd { | |
140 | cfg.header("utmp.h"); | |
141 | } else { | |
142 | cfg.header("utmpx.h"); | |
143 | } | |
144 | } | |
145 | } | |
146 | ||
147 | if apple { | |
148 | cfg.header("mach-o/dyld.h"); | |
149 | cfg.header("mach/mach_time.h"); | |
150 | cfg.header("malloc/malloc.h"); | |
151 | cfg.header("util.h"); | |
152 | cfg.header("sys/xattr.h"); | |
153 | if target.starts_with("x86") { | |
154 | cfg.header("crt_externs.h"); | |
155 | } | |
156 | } | |
157 | ||
158 | if bsdlike { | |
159 | cfg.header("sys/event.h"); | |
160 | ||
161 | if freebsd { | |
162 | cfg.header("libutil.h"); | |
163 | } else { | |
164 | cfg.header("util.h"); | |
165 | } | |
166 | } | |
167 | ||
168 | if linux { | |
169 | cfg.header("mqueue.h"); | |
170 | cfg.header("ucontext.h"); | |
171 | cfg.header("sys/signalfd.h"); | |
172 | if !uclibc { | |
173 | // optionally included in uclibc | |
174 | cfg.header("sys/xattr.h"); | |
175 | } | |
176 | cfg.header("sys/ipc.h"); | |
177 | cfg.header("sys/sem.h"); | |
178 | cfg.header("sys/msg.h"); | |
179 | cfg.header("sys/shm.h"); | |
180 | cfg.header("sys/user.h"); | |
181 | cfg.header("sys/fsuid.h"); | |
182 | cfg.header("pty.h"); | |
183 | cfg.header("shadow.h"); | |
184 | if x86_64 { | |
185 | cfg.header("sys/io.h"); | |
186 | } | |
187 | } | |
188 | ||
189 | if linux || android { | |
190 | cfg.header("malloc.h"); | |
191 | cfg.header("net/ethernet.h"); | |
192 | cfg.header("netpacket/packet.h"); | |
193 | cfg.header("sched.h"); | |
194 | cfg.header("sys/epoll.h"); | |
195 | cfg.header("sys/eventfd.h"); | |
196 | cfg.header("sys/prctl.h"); | |
197 | cfg.header("sys/sendfile.h"); | |
198 | cfg.header("sys/vfs.h"); | |
199 | cfg.header("sys/syscall.h"); | |
200 | cfg.header("sys/personality.h"); | |
201 | cfg.header("sys/swap.h"); | |
202 | if !uclibc { | |
203 | cfg.header("sys/sysinfo.h"); | |
204 | } | |
205 | cfg.header("sys/reboot.h"); | |
206 | if !musl { | |
207 | cfg.header("linux/netlink.h"); | |
208 | cfg.header("linux/magic.h"); | |
209 | cfg.header("linux/reboot.h"); | |
210 | ||
211 | if !mips { | |
212 | cfg.header("linux/quota.h"); | |
213 | } | |
214 | } | |
215 | } | |
216 | ||
217 | if freebsd { | |
218 | cfg.header("pthread_np.h"); | |
219 | cfg.header("sched.h"); | |
220 | cfg.header("ufs/ufs/quota.h"); | |
221 | cfg.header("sys/jail.h"); | |
222 | cfg.header("sys/ipc.h"); | |
223 | cfg.header("sys/msg.h"); | |
224 | cfg.header("sys/shm.h"); | |
225 | } | |
226 | ||
227 | if netbsd { | |
228 | cfg.header("ufs/ufs/quota.h"); | |
229 | cfg.header("ufs/ufs/quota1.h"); | |
230 | cfg.header("sys/ioctl_compat.h"); | |
231 | } | |
232 | ||
233 | if openbsd { | |
234 | cfg.header("ufs/ufs/quota.h"); | |
235 | cfg.header("pthread_np.h"); | |
236 | cfg.header("sys/syscall.h"); | |
237 | } | |
238 | ||
239 | if dragonfly { | |
240 | cfg.header("ufs/ufs/quota.h"); | |
241 | cfg.header("pthread_np.h"); | |
242 | cfg.header("sys/ioctl_compat.h"); | |
243 | } | |
244 | ||
245 | if linux || freebsd || dragonfly || netbsd || apple { | |
246 | if !uclibc { | |
247 | cfg.header("aio.h"); | |
248 | } | |
249 | } | |
250 | ||
251 | cfg.type_name(move |ty, is_struct| { | |
252 | match ty { | |
253 | // Just pass all these through, no need for a "struct" prefix | |
254 | "FILE" | | |
255 | "fd_set" | | |
256 | "Dl_info" | | |
257 | "DIR" => ty.to_string(), | |
258 | ||
259 | // Fixup a few types on windows that don't actually exist. | |
260 | "time64_t" if windows => "__time64_t".to_string(), | |
261 | "ssize_t" if windows => "SSIZE_T".to_string(), | |
262 | ||
263 | // OSX calls this something else | |
264 | "sighandler_t" if bsdlike => "sig_t".to_string(), | |
265 | ||
266 | t if t.ends_with("_t") => t.to_string(), | |
267 | ||
268 | // Windows uppercase structs don't have `struct` in front, there's a | |
269 | // few special cases for windows, and then otherwise put `struct` in | |
270 | // front of everything. | |
271 | t if is_struct => { | |
272 | if windows && ty.chars().next().unwrap().is_uppercase() { | |
273 | t.to_string() | |
274 | } else if windows && t == "stat" { | |
275 | "struct __stat64".to_string() | |
276 | } else if windows && t == "utimbuf" { | |
277 | "struct __utimbuf64".to_string() | |
278 | } else { | |
279 | format!("struct {}", t) | |
280 | } | |
281 | } | |
282 | ||
283 | t => t.to_string(), | |
284 | } | |
285 | }); | |
286 | ||
287 | let target2 = target.clone(); | |
288 | cfg.field_name(move |struct_, field| { | |
289 | match field { | |
290 | "st_birthtime" if openbsd && struct_ == "stat" => "__st_birthtime".to_string(), | |
291 | "st_birthtime_nsec" if openbsd && struct_ == "stat" => "__st_birthtimensec".to_string(), | |
292 | // Our stat *_nsec fields normally don't actually exist but are part | |
293 | // of a timeval struct | |
294 | s if s.ends_with("_nsec") && struct_.starts_with("stat") => { | |
295 | if target2.contains("apple") { | |
296 | s.replace("_nsec", "spec.tv_nsec") | |
297 | } else if target2.contains("android") { | |
298 | s.to_string() | |
299 | } else { | |
300 | s.replace("e_nsec", ".tv_nsec") | |
301 | } | |
302 | } | |
303 | "u64" if struct_ == "epoll_event" => "data.u64".to_string(), | |
304 | s => s.to_string(), | |
305 | } | |
306 | }); | |
307 | ||
308 | cfg.skip_type(move |ty| { | |
309 | match ty { | |
310 | // sighandler_t is crazy across platforms | |
311 | "sighandler_t" => true, | |
312 | ||
313 | _ => false | |
314 | } | |
315 | }); | |
316 | ||
317 | cfg.skip_struct(move |ty| { | |
318 | match ty { | |
319 | "sockaddr_nl" => musl, | |
320 | ||
321 | // On Linux, the type of `ut_tv` field of `struct utmpx` | |
322 | // can be an anonymous struct, so an extra struct, | |
323 | // which is absent in glibc, has to be defined. | |
324 | "__timeval" if linux => true, | |
325 | ||
326 | // The alignment of this is 4 on 64-bit OSX... | |
327 | "kevent" if apple && x86_64 => true, | |
328 | ||
329 | // This is actually a union, not a struct | |
330 | "sigval" => true, | |
331 | ||
332 | _ => false | |
333 | } | |
334 | }); | |
335 | ||
336 | cfg.skip_signededness(move |c| { | |
337 | match c { | |
338 | "LARGE_INTEGER" | | |
339 | "mach_timebase_info_data_t" | | |
340 | "float" | | |
341 | "double" => true, | |
342 | // uuid_t is a struct, not an integer. | |
343 | "uuid_t" if dragonfly => true, | |
344 | n if n.starts_with("pthread") => true, | |
345 | // sem_t is a struct or pointer | |
346 | "sem_t" if openbsd || freebsd || dragonfly || rumprun => true, | |
347 | ||
348 | // windows-isms | |
349 | n if n.starts_with("P") => true, | |
350 | n if n.starts_with("H") => true, | |
351 | n if n.starts_with("LP") => true, | |
352 | _ => false, | |
353 | } | |
354 | }); | |
355 | ||
356 | cfg.skip_const(move |name| { | |
357 | match name { | |
358 | // Apparently these don't exist in mingw headers? | |
359 | "MEM_RESET_UNDO" | | |
360 | "FILE_ATTRIBUTE_NO_SCRUB_DATA" | | |
361 | "FILE_ATTRIBUTE_INTEGRITY_STREAM" | | |
362 | "ERROR_NOTHING_TO_TERMINATE" if mingw => true, | |
363 | ||
364 | "SIG_IGN" => true, // sighandler_t weirdness | |
365 | ||
366 | // types on musl are defined a little differently | |
367 | n if musl && n.contains("__SIZEOF_PTHREAD") => true, | |
368 | ||
369 | // Skip constants not defined in MUSL but just passed down to the | |
370 | // kernel regardless | |
371 | "RLIMIT_NLIMITS" | | |
372 | "TCP_COOKIE_TRANSACTIONS" | | |
373 | "RLIMIT_RTTIME" | | |
374 | "MSG_COPY" if musl => true, | |
375 | // work around super old mips toolchain | |
376 | "SCHED_IDLE" | "SHM_NORESERVE" => mips, | |
377 | ||
378 | // weird signed extension or something like that? | |
379 | "MS_NOUSER" => true, | |
380 | "MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13 | |
381 | ||
382 | // These OSX constants are flagged as deprecated | |
383 | "NOTE_EXIT_REPARENTED" | | |
384 | "NOTE_REAP" if apple => true, | |
385 | ||
386 | // The linux/quota.h header file which defines these can't be | |
387 | // included with sys/quota.h currently on MIPS, so we don't include | |
388 | // it and just ignore these constants | |
389 | "QFMT_VFS_OLD" | | |
390 | "QFMT_VFS_V0" if mips && linux => true, | |
391 | ||
392 | // These constants were removed in FreeBSD 11 (svn r273250) but will | |
393 | // still be accepted and ignored at runtime. | |
394 | "MAP_RENAME" | | |
395 | "MAP_NORESERVE" if freebsd => true, | |
396 | ||
397 | // These constants were removed in FreeBSD 11 (svn r262489), | |
398 | // and they've never had any legitimate use outside of the | |
399 | // base system anyway. | |
400 | "CTL_MAXID" | | |
401 | "KERN_MAXID" | | |
402 | "HW_MAXID" | | |
403 | "USER_MAXID" if freebsd => true, | |
404 | ||
405 | // These OSX constants are removed in Sierra. | |
406 | // https://developer.apple.com/library/content/releasenotes/General/APIDiffsMacOS10_12/Swift/Darwin.html | |
407 | "KERN_KDENABLE_BG_TRACE" if apple => true, | |
408 | "KERN_KDDISABLE_BG_TRACE" if apple => true, | |
409 | ||
410 | // These are either unimplemented or optionally built into uClibc | |
411 | "LC_CTYPE_MASK" | "LC_NUMERIC_MASK" | "LC_TIME_MASK" | "LC_COLLATE_MASK" | "LC_MONETARY_MASK" | "LC_MESSAGES_MASK" | | |
412 | "MADV_MERGEABLE" | "MADV_UNMERGEABLE" | "MADV_HWPOISON" | "IPV6_ADD_MEMBERSHIP" | "IPV6_DROP_MEMBERSHIP" | "IPV6_MULTICAST_LOOP" | "IPV6_V6ONLY" | | |
413 | "MAP_STACK" | "RTLD_DEEPBIND" | "SOL_IPV6" | "SOL_ICMPV6" if uclibc => true, | |
414 | ||
415 | // Defined by libattr not libc on linux (hard to test). | |
416 | // See constant definition for more details. | |
417 | "ENOATTR" if linux => true, | |
418 | ||
419 | _ => false, | |
420 | } | |
421 | }); | |
422 | ||
423 | cfg.skip_fn(move |name| { | |
424 | // skip those that are manually verified | |
425 | match name { | |
426 | "execv" | // crazy stuff with const/mut | |
427 | "execve" | | |
428 | "execvp" | | |
429 | "execvpe" => true, | |
430 | ||
431 | "getrlimit" | "getrlimit64" | // non-int in 1st arg | |
432 | "setrlimit" | "setrlimit64" | // non-int in 1st arg | |
433 | "prlimit" | "prlimit64" | // non-int in 2nd arg | |
434 | "strerror_r" if linux => true, // actually xpg-something-or-other | |
435 | ||
436 | // int vs uint. Sorry musl, your prototype declarations are "correct" in the sense that | |
437 | // they match the interface defined by Linux verbatim, but they conflict with other | |
438 | // send*/recv* syscalls | |
439 | "sendmmsg" | "recvmmsg" if musl => true, | |
440 | ||
441 | // typed 2nd arg on linux and android | |
442 | "gettimeofday" if linux || android || freebsd || openbsd || dragonfly => true, | |
443 | ||
444 | // not declared in newer android toolchains | |
445 | "getdtablesize" if android => true, | |
446 | ||
447 | "dlerror" if android => true, // const-ness is added | |
448 | "dladdr" if musl => true, // const-ness only added recently | |
449 | ||
450 | // OSX has 'struct tm *const' which we can't actually represent in | |
451 | // Rust, but is close enough to *mut | |
452 | "timegm" if apple => true, | |
453 | ||
454 | // OSX's daemon is deprecated in 10.5 so we'll get a warning (which | |
455 | // we turn into an error) so just ignore it. | |
456 | "daemon" if apple => true, | |
457 | ||
458 | // Deprecated on OSX | |
459 | "sem_destroy" if apple => true, | |
460 | "sem_init" if apple => true, | |
461 | ||
462 | // These functions presumably exist on netbsd but don't look like | |
463 | // they're implemented on rumprun yet, just let them slide for now. | |
464 | // Some of them look like they have headers but then don't have | |
465 | // corresponding actual definitions either... | |
466 | "shm_open" | | |
467 | "shm_unlink" | | |
468 | "syscall" | | |
469 | "ptrace" | | |
470 | "sigaltstack" if rumprun => true, | |
471 | ||
472 | // There seems to be a small error in EGLIBC's eventfd.h header. The | |
473 | // [underlying system call][1] always takes its first `count` | |
474 | // argument as an `unsigned int`, but [EGLIBC's <sys/eventfd.h> | |
475 | // header][2] declares it to take an `int`. [GLIBC's header][3] | |
476 | // matches the kernel. | |
477 | // | |
478 | // EGLIBC is no longer actively developed, and Debian, the largest | |
479 | // distribution that had been using it, switched back to GLIBC in | |
480 | // April 2015. So effectively all Linux <sys/eventfd.h> headers will | |
481 | // be using `unsigned int` soon. | |
482 | // | |
483 | // [1]: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/fs/eventfd.c?id=refs/tags/v3.12.51#n397 | |
484 | // [2]: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/eglibc/trusty/view/head:/sysdeps/unix/sysv/linux/sys/eventfd.h | |
485 | // [3]: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sys/eventfd.h;h=6295f32e937e779e74318eb9d3bdbe76aef8a8f3;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l34 | |
486 | "eventfd" if linux => true, | |
487 | ||
488 | // The `uname` function in freebsd is now an inline wrapper that | |
489 | // delegates to another, but the symbol still exists, so don't check | |
490 | // the symbol. | |
491 | "uname" if freebsd => true, | |
492 | ||
493 | // aio_waitcomplete's return type changed between FreeBSD 10 and 11. | |
494 | "aio_waitcomplete" if freebsd => true, | |
495 | ||
496 | // lio_listio confuses the checker, probably because one of its | |
497 | // arguments is an array | |
498 | "lio_listio" if freebsd => true, | |
499 | "lio_listio" if musl => true, | |
500 | ||
501 | // Apparently the NDK doesn't have this defined on android, but | |
502 | // it's in a header file? | |
503 | "endpwent" if android => true, | |
504 | ||
505 | ||
506 | // These are either unimplemented or optionally built into uClibc | |
507 | // or "sysinfo", where it's defined but the structs in linux/sysinfo.h and sys/sysinfo.h | |
508 | // clash so it can't be tested | |
509 | "getxattr" | "lgetxattr" | "fgetxattr" | "setxattr" | "lsetxattr" | "fsetxattr" | | |
510 | "listxattr" | "llistxattr" | "flistxattr" | "removexattr" | "lremovexattr" | | |
511 | "fremovexattr" | | |
512 | "backtrace" | | |
513 | "sysinfo" | "newlocale" | "duplocale" | "freelocale" | "uselocale" | | |
514 | "nl_langinfo_l" | "wcslen" | "wcstombs" if uclibc => true, | |
515 | ||
516 | // Apparently res_init exists on Android, but isn't defined in a header: | |
517 | // https://mail.gnome.org/archives/commits-list/2013-May/msg01329.html | |
518 | "res_init" if android => true, | |
519 | ||
520 | // On macOS and iOS, res_init is available, but requires linking with libresolv: | |
521 | // http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html | |
522 | // See discussion for skipping here: | |
523 | // https://github.com/rust-lang/libc/pull/585#discussion_r114561460 | |
524 | "res_init" if apple => true, | |
525 | ||
526 | // On Mac we don't use the default `close()`, instead using their $NOCANCEL variants. | |
527 | "close" if apple => true, | |
528 | ||
529 | _ => false, | |
530 | } | |
531 | }); | |
532 | ||
533 | cfg.skip_fn_ptrcheck(move |name| { | |
534 | match name { | |
535 | // dllimport weirdness? | |
536 | _ if windows => true, | |
537 | ||
538 | _ => false, | |
539 | } | |
540 | }); | |
541 | ||
542 | cfg.skip_field_type(move |struct_, field| { | |
543 | // This is a weird union, don't check the type. | |
544 | (struct_ == "ifaddrs" && field == "ifa_ifu") || | |
545 | // sighandler_t type is super weird | |
546 | (struct_ == "sigaction" && field == "sa_sigaction") || | |
547 | // __timeval type is a patch which doesn't exist in glibc | |
548 | (linux && struct_ == "utmpx" && field == "ut_tv") || | |
549 | // sigval is actually a union, but we pretend it's a struct | |
550 | (struct_ == "sigevent" && field == "sigev_value") || | |
551 | // aio_buf is "volatile void*" and Rust doesn't understand volatile | |
552 | (struct_ == "aiocb" && field == "aio_buf") || | |
553 | // stack_t.ss_sp's type changed from FreeBSD 10 to 11 in svn r294930 | |
554 | (freebsd && struct_ == "stack_t" && field == "ss_sp") | |
555 | }); | |
556 | ||
557 | cfg.skip_field(move |struct_, field| { | |
558 | // this is actually a union on linux, so we can't represent it well and | |
559 | // just insert some padding. | |
560 | (struct_ == "siginfo_t" && field == "_pad") || | |
561 | // musl names this __dummy1 but it's still there | |
562 | (musl && struct_ == "glob_t" && field == "gl_flags") || | |
563 | // musl seems to define this as an *anonymous* bitfield | |
564 | (musl && struct_ == "statvfs" && field == "__f_unused") || | |
565 | // sigev_notify_thread_id is actually part of a sigev_un union | |
566 | (struct_ == "sigevent" && field == "sigev_notify_thread_id") | |
567 | }); | |
568 | ||
569 | cfg.fn_cname(move |name, cname| { | |
570 | if windows { | |
571 | cname.unwrap_or(name).to_string() | |
572 | } else { | |
573 | name.to_string() | |
574 | } | |
575 | }); | |
576 | ||
577 | if env::var("SKIP_COMPILE").is_ok() { | |
578 | cfg.generate_files("../src/lib.rs", "all.rs"); | |
579 | } else { | |
580 | cfg.generate("../src/lib.rs", "all.rs"); | |
581 | } | |
582 | } |