]>
git.proxmox.com Git - rustc.git/blob - src/liblibc/libc-test/build.rs
8 let target
= env
::var("TARGET").unwrap();
9 let windows
= target
.contains("windows");
10 let mingw
= target
.contains("windows-gnu");
11 let linux
= target
.contains("unknown-linux");
12 let android
= target
.contains("android");
13 let apple
= target
.contains("apple");
14 let musl
= target
.contains("musl");
15 let freebsd
= target
.contains("freebsd");
16 let bsdlike
= freebsd
|| apple
;
17 let mut cfg
= ctest
::TestGenerator
::new();
19 // Pull in extra goodies on linux/mingw
20 if target
.contains("unknown-linux") {
21 cfg
.define("_GNU_SOURCE", None
);
23 cfg
.define("_WIN32_WINNT", Some("0x8000"));
26 // Android doesn't actually have in_port_t but it's much easier if we
27 // provide one for us to test against
29 cfg
.define("in_port_t", Some("uint16_t"));
40 .header("sys/types.h")
45 cfg
.header("winsock2.h"); // must be before windows.h
47 cfg
.header("direct.h");
49 cfg
.header("sys/utime.h");
50 cfg
.header("windows.h");
51 cfg
.header("process.h");
52 cfg
.header("ws2ipdef.h");
54 if target
.contains("gnu") {
55 cfg
.header("ws2tcpip.h");
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");
66 cfg
.header("dlfcn.h");
67 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");
84 cfg
.header("arpa/inet.h");
85 cfg
.header("time64.h");
88 cfg
.header("ifaddrs.h");
89 cfg
.header("sys/statvfs.h");
92 cfg
.header("execinfo.h");
93 cfg
.header("sys/sysctl.h");
98 cfg
.header("mach-o/dyld.h");
99 cfg
.header("mach/mach_time.h");
100 cfg
.header("malloc/malloc.h");
101 if target
.starts_with("x86") {
102 cfg
.header("crt_externs.h");
106 if linux
|| android
{
107 cfg
.header("netpacket/packet.h");
108 cfg
.header("net/ethernet.h");
109 cfg
.header("malloc.h");
110 cfg
.header("sys/prctl.h");
111 /* linux kernel header */
113 cfg
.header("linux/netlink.h");
118 cfg
.header("pthread_np.h");
121 cfg
.type_name(move |ty
, is_struct
| {
123 // Just pass all these through, no need for a "struct" prefix
127 "DIR" => ty
.to_string(),
129 // Fixup a few types on windows that don't actually exist.
130 "time64_t" if windows
=> "__time64_t".to_string(),
131 "ssize_t" if windows
=> "SSIZE_T".to_string(),
133 // OSX calls this something else
134 "sighandler_t" if bsdlike
=> "sig_t".to_string(),
136 t
if t
.ends_with("_t") => t
.to_string(),
138 // Windows uppercase structs don't have `struct` in front, there's a
139 // few special cases for windows, and then otherwise put `struct` in
140 // front of everything.
142 if windows
&& ty
.chars().next().unwrap().is_uppercase() {
144 } else if windows
&& t
== "stat" {
145 "struct __stat64".to_string()
146 } else if windows
&& t
== "utimbuf" {
147 "struct __utimbuf64".to_string()
149 format
!("struct {}", t
)
157 let target2
= target
.clone();
158 cfg
.field_name(move |struct_
, field
| {
160 // Our stat *_nsec fields normally don't actually exist but are part
161 // of a timeval struct
162 s
if s
.ends_with("_nsec") && struct_
.starts_with("stat") => {
163 if target2
.contains("apple") {
164 s
.replace("_nsec", "spec.tv_nsec")
165 } else if target2
.contains("android") {
168 s
.replace("e_nsec", ".tv_nsec")
175 cfg
.skip_type(move |ty
| {
177 // sighandler_t is crazy across platforms
178 "sighandler_t" => true,
184 cfg
.skip_struct(move |ty
| {
186 "sockaddr_nl" => musl
,
191 cfg
.skip_signededness(|c
| {
194 "mach_timebase_info_data_t" |
197 n
if n
.starts_with("pthread") => true,
200 n
if n
.starts_with("P") => true,
201 n
if n
.starts_with("H") => true,
202 n
if n
.starts_with("LP") => true,
207 cfg
.skip_const(move |name
| {
209 // Apparently these don't exist in mingw headers?
211 "FILE_ATTRIBUTE_NO_SCRUB_DATA" |
212 "FILE_ATTRIBUTE_INTEGRITY_STREAM" |
213 "ERROR_NOTHING_TO_TERMINATE" if mingw
=> true,
215 "SIG_IGN" => true, // sighandler_t weirdness
217 // types on musl are defined a little differently
218 n
if musl
&& n
.contains("__SIZEOF_PTHREAD") => true,
220 // Skip constants not defined in MUSL but just passed down to the
223 "TCP_COOKIE_TRANSACTIONS" |
224 "RLIMIT_RTTIME" if musl
=> true,
230 cfg
.skip_fn(move |name
| {
231 // skip those that are manually verifiedmanually verified
233 "execv" | // crazy stuff with const/mut
238 "getrlimit" | "getrlimit64" | // non-int in 1st arg
239 "setrlimit" | "setrlimit64" | // non-int in 1st arg
240 "strerror_r" if linux
=> true, // actually xpg-something-or-other
242 // typed 2nd arg on linux and android
243 "gettimeofday" if linux
|| android
|| freebsd
=> true,
245 "dlerror" if android
=> true, // const-ness is added
246 "dladdr" if musl
=> true, // const-ness only added recently
248 // OSX has 'struct tm *const' which we can't actually represent in
249 // Rust, but is close enough to *mut
250 "timegm" if apple
=> true,
256 // Windows dllimport oddness?
257 cfg
.skip_fn_ptrcheck(move |_
| windows
);
259 cfg
.skip_field_type(move |struct_
, field
| {
260 // This is a weird union, don't check the type.
261 (struct_
== "ifaddrs" && field
== "ifa_ifu") ||
262 // sighandler_t type is super weird
263 (struct_
== "sigaction" && field
== "sa_sigaction")
266 cfg
.skip_field(move |struct_
, field
| {
267 // this is actually a union on linux, so we can't represent it well and
268 // just insert some padding.
269 (struct_
== "siginfo_t" && field
== "_pad") ||
270 // musl names this __dummy1 but it's still there
271 (musl
&& struct_
== "glob_t" && field
== "gl_flags")
274 cfg
.generate("../src/lib.rs", "all.rs");