]>
git.proxmox.com Git - rustc.git/blob - src/liblibc/libc-test/build.rs
8 let target
= env
::var("TARGET").unwrap();
9 let x86_64
= target
.contains("x86_64");
10 let windows
= target
.contains("windows");
11 let mingw
= target
.contains("windows-gnu");
12 let linux
= target
.contains("unknown-linux");
13 let android
= target
.contains("android");
14 let apple
= target
.contains("apple");
15 let musl
= target
.contains("musl");
16 let freebsd
= target
.contains("freebsd");
17 let dragonfly
= target
.contains("dragonfly");
18 let mips
= target
.contains("mips");
19 let netbsd
= target
.contains("netbsd");
20 let openbsd
= target
.contains("openbsd");
21 let rumprun
= target
.contains("rumprun");
22 let bsdlike
= freebsd
|| apple
|| netbsd
|| openbsd
|| dragonfly
;
23 let mut cfg
= ctest
::TestGenerator
::new();
25 // Pull in extra goodies on linux/mingw
27 cfg
.define("_GNU_SOURCE", None
);
29 cfg
.define("_WIN32_WINNT", Some("0x8000"));
32 // Android doesn't actually have in_port_t but it's much easier if we
33 // provide one for us to test against
35 cfg
.define("in_port_t", Some("uint16_t"));
47 .header("sys/types.h")
52 cfg
.header("winsock2.h"); // must be before windows.h
54 cfg
.header("direct.h");
56 cfg
.header("sys/utime.h");
57 cfg
.header("windows.h");
58 cfg
.header("process.h");
59 cfg
.header("ws2ipdef.h");
61 if target
.contains("gnu") {
62 cfg
.header("ws2tcpip.h");
65 cfg
.header("ctype.h");
66 cfg
.header("dirent.h");
68 cfg
.header("sys/socket.h");
70 cfg
.header("net/if.h");
71 cfg
.header("netdb.h");
72 cfg
.header("netinet/in.h");
73 cfg
.header("netinet/ip.h");
74 cfg
.header("netinet/tcp.h");
75 cfg
.header("pthread.h");
76 cfg
.header("dlfcn.h");
77 cfg
.header("signal.h");
78 cfg
.header("string.h");
79 cfg
.header("sys/file.h");
80 cfg
.header("sys/ioctl.h");
81 cfg
.header("sys/mman.h");
82 cfg
.header("sys/resource.h");
83 cfg
.header("sys/socket.h");
84 cfg
.header("sys/time.h");
85 cfg
.header("sys/un.h");
86 cfg
.header("sys/wait.h");
87 cfg
.header("unistd.h");
88 cfg
.header("utime.h");
91 cfg
.header("sys/utsname.h");
92 cfg
.header("sys/ptrace.h");
93 cfg
.header("sys/mount.h");
94 cfg
.header("sys/uio.h");
95 cfg
.header("sched.h");
96 cfg
.header("termios.h");
101 cfg
.header("arpa/inet.h");
102 cfg
.header("time64.h");
104 cfg
.header("glob.h");
105 cfg
.header("ifaddrs.h");
106 cfg
.header("sys/statvfs.h");
108 if !openbsd
&& !freebsd
&& !dragonfly
{
109 cfg
.header("sys/quota.h");
113 cfg
.header("sys/sysctl.h");
115 if !netbsd
&& !openbsd
{
116 cfg
.header("execinfo.h");
122 cfg
.header("mach-o/dyld.h");
123 cfg
.header("mach/mach_time.h");
124 cfg
.header("malloc/malloc.h");
125 cfg
.header("util.h");
126 if target
.starts_with("x86") {
127 cfg
.header("crt_externs.h");
132 cfg
.header("sys/event.h");
135 cfg
.header("libutil.h");
137 cfg
.header("util.h");
142 cfg
.header("mqueue.h");
143 cfg
.header("ucontext.h");
144 cfg
.header("sys/signalfd.h");
145 cfg
.header("sys/xattr.h");
146 cfg
.header("sys/ipc.h");
147 cfg
.header("sys/shm.h");
151 if linux
|| android
{
152 cfg
.header("malloc.h");
153 cfg
.header("net/ethernet.h");
154 cfg
.header("netpacket/packet.h");
155 cfg
.header("sched.h");
156 cfg
.header("sys/epoll.h");
157 cfg
.header("sys/eventfd.h");
158 cfg
.header("sys/prctl.h");
159 cfg
.header("sys/sendfile.h");
160 cfg
.header("sys/vfs.h");
161 cfg
.header("sys/syscall.h");
163 cfg
.header("linux/netlink.h");
164 cfg
.header("linux/magic.h");
167 cfg
.header("linux/quota.h");
173 cfg
.header("pthread_np.h");
174 cfg
.header("sched.h");
175 cfg
.header("ufs/ufs/quota.h");
179 cfg
.header("ufs/ufs/quota.h");
180 cfg
.header("ufs/ufs/quota1.h");
181 cfg
.header("sys/ioctl_compat.h");
185 cfg
.header("ufs/ufs/quota.h");
186 cfg
.header("rpcsvc/rex.h");
187 cfg
.header("pthread_np.h");
188 cfg
.header("sys/syscall.h");
192 cfg
.header("ufs/ufs/quota.h");
193 cfg
.header("pthread_np.h");
194 cfg
.header("sys/ioctl_compat.h");
197 cfg
.type_name(move |ty
, is_struct
| {
199 // Just pass all these through, no need for a "struct" prefix
203 "DIR" => ty
.to_string(),
205 // Fixup a few types on windows that don't actually exist.
206 "time64_t" if windows
=> "__time64_t".to_string(),
207 "ssize_t" if windows
=> "SSIZE_T".to_string(),
209 // OSX calls this something else
210 "sighandler_t" if bsdlike
=> "sig_t".to_string(),
212 t
if t
.ends_with("_t") => t
.to_string(),
214 // Windows uppercase structs don't have `struct` in front, there's a
215 // few special cases for windows, and then otherwise put `struct` in
216 // front of everything.
218 if windows
&& ty
.chars().next().unwrap().is_uppercase() {
220 } else if windows
&& t
== "stat" {
221 "struct __stat64".to_string()
222 } else if windows
&& t
== "utimbuf" {
223 "struct __utimbuf64".to_string()
225 format
!("struct {}", t
)
233 let target2
= target
.clone();
234 cfg
.field_name(move |struct_
, field
| {
236 "st_birthtime" if openbsd
&& struct_
== "stat" => "__st_birthtime".to_string(),
237 "st_birthtime_nsec" if openbsd
&& struct_
== "stat" => "__st_birthtimensec".to_string(),
238 // Our stat *_nsec fields normally don't actually exist but are part
239 // of a timeval struct
240 s
if s
.ends_with("_nsec") && struct_
.starts_with("stat") => {
241 if target2
.contains("apple") {
242 s
.replace("_nsec", "spec.tv_nsec")
243 } else if target2
.contains("android") {
246 s
.replace("e_nsec", ".tv_nsec")
249 "u64" if struct_
== "epoll_event" => "data.u64".to_string(),
254 cfg
.skip_type(move |ty
| {
256 // sighandler_t is crazy across platforms
257 "sighandler_t" => true,
263 cfg
.skip_struct(move |ty
| {
265 "sockaddr_nl" => musl
,
267 // The alignment of this is 4 on 64-bit OSX...
268 "kevent" if apple
&& x86_64
=> true,
274 cfg
.skip_signededness(move |c
| {
277 "mach_timebase_info_data_t" |
280 // uuid_t is a struct, not an integer.
281 "uuid_t" if dragonfly
=> true,
282 n
if n
.starts_with("pthread") => true,
285 n
if n
.starts_with("P") => true,
286 n
if n
.starts_with("H") => true,
287 n
if n
.starts_with("LP") => true,
292 cfg
.skip_const(move |name
| {
294 // Apparently these don't exist in mingw headers?
296 "FILE_ATTRIBUTE_NO_SCRUB_DATA" |
297 "FILE_ATTRIBUTE_INTEGRITY_STREAM" |
298 "ERROR_NOTHING_TO_TERMINATE" if mingw
=> true,
300 "SIG_IGN" => true, // sighandler_t weirdness
302 // types on musl are defined a little differently
303 n
if musl
&& n
.contains("__SIZEOF_PTHREAD") => true,
305 // Skip constants not defined in MUSL but just passed down to the
308 "TCP_COOKIE_TRANSACTIONS" |
309 "RLIMIT_RTTIME" if musl
=> true,
310 // work around super old mips toolchain
311 "SCHED_IDLE" | "SHM_NORESERVE" => mips
,
313 // weird signed extension or something like that?
315 "MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13
317 // These OSX constants are flagged as deprecated
318 "NOTE_EXIT_REPARENTED" |
319 "NOTE_REAP" if apple
=> true,
321 // The linux/quota.h header file which defines these can't be
322 // included with sys/quota.h currently on MIPS, so we don't include
323 // it and just ignore these constants
325 "QFMT_VFS_V0" if mips
&& linux
=> true,
331 cfg
.skip_fn(move |name
| {
332 // skip those that are manually verified
334 "execv" | // crazy stuff with const/mut
339 "getrlimit" | "getrlimit64" | // non-int in 1st arg
340 "setrlimit" | "setrlimit64" | // non-int in 1st arg
341 "strerror_r" if linux
=> true, // actually xpg-something-or-other
343 // typed 2nd arg on linux and android
344 "gettimeofday" if linux
|| android
|| freebsd
|| openbsd
|| dragonfly
=> true,
346 // not declared in newer android toolchains
347 "getdtablesize" if android
=> true,
349 "dlerror" if android
=> true, // const-ness is added
350 "dladdr" if musl
=> true, // const-ness only added recently
352 // OSX has 'struct tm *const' which we can't actually represent in
353 // Rust, but is close enough to *mut
354 "timegm" if apple
=> true,
356 // OSX's daemon is deprecated in 10.5 so we'll get a warning (which
357 // we turn into an error) so just ignore it.
358 "daemon" if apple
=> true,
360 // These functions presumably exist on netbsd but don't look like
361 // they're implemented on rumprun yet, just let them slide for now.
362 // Some of them look like they have headers but then don't have
363 // corresponding actual definitions either...
368 "sigaltstack" if rumprun
=> true,
370 // There seems to be a small error in EGLIBC's eventfd.h header. The
371 // [underlying system call][1] always takes its first `count`
372 // argument as an `unsigned int`, but [EGLIBC's <sys/eventfd.h>
373 // header][2] declares it to take an `int`. [GLIBC's header][3]
374 // matches the kernel.
376 // EGLIBC is no longer actively developed, and Debian, the largest
377 // distribution that had been using it, switched back to GLIBC in
378 // April 2015. So effectively all Linux <sys/eventfd.h> headers will
379 // be using `unsigned int` soon.
381 // [1]: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/fs/eventfd.c?id=refs/tags/v3.12.51#n397
382 // [2]: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/eglibc/trusty/view/head:/sysdeps/unix/sysv/linux/sys/eventfd.h
383 // [3]: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sys/eventfd.h;h=6295f32e937e779e74318eb9d3bdbe76aef8a8f3;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l34
384 "eventfd" if linux
=> true,
386 // The `uname` funcion in freebsd is now an inline wrapper that
387 // delegates to another, but the symbol still exists, so don't check
389 "uname" if freebsd
=> true,
395 cfg
.skip_fn_ptrcheck(move |name
| {
397 // This used to be called bsd_signal in rev 18 of the android
398 // platform and is now just called signal, the old `bsd_signal`
399 // symbol, however, still remains, just gives a different function
401 "signal" if android
=> true,
403 // dllimport weirdness?
404 _
if windows
=> true,
410 cfg
.skip_field_type(move |struct_
, field
| {
411 // This is a weird union, don't check the type.
412 (struct_
== "ifaddrs" && field
== "ifa_ifu") ||
413 // sighandler_t type is super weird
414 (struct_
== "sigaction" && field
== "sa_sigaction")
417 cfg
.skip_field(move |struct_
, field
| {
418 // this is actually a union on linux, so we can't represent it well and
419 // just insert some padding.
420 (struct_
== "siginfo_t" && field
== "_pad") ||
421 // musl names this __dummy1 but it's still there
422 (musl
&& struct_
== "glob_t" && field
== "gl_flags") ||
423 // musl seems to define this as an *anonymous* bitfield
424 (musl
&& struct_
== "statvfs" && field
== "__f_unused")
427 cfg
.fn_cname(move |name
, cname
| {
429 cname
.unwrap_or(name
).to_string()
435 if env
::var("SKIP_COMPILE").is_ok() {
436 cfg
.generate_files("../src/lib.rs", "all.rs");
438 cfg
.generate("../src/lib.rs", "all.rs");