@@ -57,6 +57,7 @@ fn do_ctest() {
5757 t if t. contains ( "emscripten" ) => test_emscripten ( t) ,
5858 t if t. contains ( "freebsd" ) => test_freebsd ( t) ,
5959 t if t. contains ( "haiku" ) => test_haiku ( t) ,
60+ t if t. contains ( "l4re" ) => test_linux ( t) ,
6061 t if t. contains ( "linux" ) => test_linux ( t) ,
6162 t if t. contains ( "netbsd" ) => test_netbsd ( t) ,
6263 t if t. contains ( "openbsd" ) => test_openbsd ( t) ,
@@ -96,9 +97,10 @@ fn do_semver() {
9697 // NOTE: Android doesn't include the unix file (or the Linux file) because
9798 // there are some many definitions missing it's actually easier just to
9899 // maintain a file for Android.
99- // NOTE: AIX doesn't include the unix file because there are definitions
100- // missing on AIX. It is easier to maintain a file for AIX.
101- if family != os && !matches ! ( os. as_str( ) , "android" | "aix" ) {
100+ // NOTE: AIX and L4Re do not include the unix file because there are
101+ // definitions missing on these systems. It is easier to maintain separate
102+ // files for them.
103+ if family != os && !matches ! ( os. as_str( ) , "android" | "aix" | "l4re" ) {
102104 process_semver_file ( & mut output, & mut semver_root, & family) ;
103105 }
104106 // We don't do semver for unknown targets.
@@ -3660,18 +3662,26 @@ fn config_gnu_bits(target: &str, cfg: &mut ctest::TestGenerator) {
36603662}
36613663
36623664fn test_linux ( target : & str ) {
3663- assert ! ( target. contains( "linux" ) ) ;
3665+ assert ! ( target. contains( "linux" ) || target. contains( "l4re" ) ) ;
3666+
3667+ // target_os
3668+ let linux = target. contains ( "linux" ) ;
3669+ let l4re = target. contains ( "l4re" ) ;
36643670
36653671 // target_env
36663672 let gnu = target. contains ( "gnu" ) ;
36673673 let musl = target. contains ( "musl" ) || target. contains ( "ohos" ) ;
36683674 let uclibc = target. contains ( "uclibc" ) ;
36693675
3670- match ( gnu, musl, uclibc) {
3671- ( true , false , false ) => ( ) ,
3672- ( false , true , false ) => ( ) ,
3673- ( false , false , true ) => ( ) ,
3674- ( _, _, _) => panic ! ( "linux target lib is gnu: {gnu}, musl: {musl}, uclibc: {uclibc}" ) ,
3676+ match ( linux, gnu, musl, uclibc) {
3677+ ( true , true , false , false ) => ( ) ,
3678+ ( true , false , true , false ) => ( ) ,
3679+ ( true , false , false , true ) => ( ) ,
3680+ ( false , false , false , true ) => ( ) ,
3681+ ( _, _, _, _) => panic ! (
3682+ "{} target lib is gnu: {gnu}, musl: {musl}, uclibc: {uclibc}" ,
3683+ if linux { "linux" } else { "l4re" }
3684+ ) ,
36753685 }
36763686
36773687 let arm = target. contains ( "arm" ) ;
@@ -3703,8 +3713,10 @@ fn test_linux(target: &str) {
37033713 // deprecated since glibc >= 2.29. This allows Rust binaries to link against
37043714 // glibc versions older than 2.29.
37053715 cfg. define ( "__GLIBC_USE_DEPRECATED_SCANF" , None ) ;
3706-
37073716 config_gnu_bits ( target, & mut cfg) ;
3717+ if l4re {
3718+ cfg. flag ( "-Wno-unused-function" ) ;
3719+ }
37083720
37093721 headers ! { cfg:
37103722 "ctype.h" ,
@@ -3723,11 +3735,12 @@ fn test_linux(target: &str) {
37233735 "libgen.h" ,
37243736 "limits.h" ,
37253737 "link.h" ,
3726- "linux/sysctl.h" ,
3738+ [ uclibc] : "linux/if_ether.h" ,
3739+ [ !l4re] : "linux/sysctl.h" ,
37273740 "locale.h" ,
37283741 "malloc.h" ,
37293742 "mntent.h" ,
3730- "mqueue.h" ,
3743+ [ !l4re ] : "mqueue.h" ,
37313744 "net/ethernet.h" ,
37323745 "net/if.h" ,
37333746 "net/if_arp.h" ,
@@ -3737,6 +3750,7 @@ fn test_linux(target: &str) {
37373750 "netinet/ip.h" ,
37383751 "netinet/tcp.h" ,
37393752 "netinet/udp.h" ,
3753+ [ l4re] : "netpacket/packet.h" ,
37403754 "poll.h" ,
37413755 "pthread.h" ,
37423756 "pty.h" ,
@@ -3747,43 +3761,44 @@ fn test_linux(target: &str) {
37473761 "semaphore.h" ,
37483762 "shadow.h" ,
37493763 "signal.h" ,
3750- "spawn.h" ,
3751- "stddef.h" ,
3764+ [ !l4re ] : "spawn.h" ,
3765+ [ !l4re ] : "stddef.h" ,
37523766 "stdint.h" ,
37533767 "stdio.h" ,
37543768 "stdlib.h" ,
37553769 "string.h" ,
3756- "sys/epoll.h" ,
3757- "sys/eventfd.h" ,
3770+ [ l4re] : "sys/auxv.h" ,
3771+ [ !l4re] : "sys/epoll.h" ,
3772+ [ !l4re] : "sys/eventfd.h" ,
37583773 "sys/file.h" ,
3759- "sys/fsuid.h" ,
3760- "sys/klog.h" ,
3761- "sys/inotify.h" ,
3774+ [ !l4re ] : "sys/fsuid.h" ,
3775+ [ !l4re ] : "sys/klog.h" ,
3776+ [ !l4re ] : "sys/inotify.h" ,
37623777 "sys/ioctl.h" ,
37633778 "sys/ipc.h" ,
37643779 "sys/mman.h" ,
37653780 "sys/mount.h" ,
3766- "sys/msg.h" ,
3767- "sys/personality.h" ,
3781+ [ !l4re ] : "sys/msg.h" ,
3782+ [ !l4re ] : "sys/personality.h" ,
37683783 "sys/prctl.h" ,
3769- "sys/ptrace.h" ,
3770- "sys/quota.h" ,
3771- "sys/random.h" ,
3772- "sys/reboot.h" ,
3784+ [ !l4re ] : "sys/ptrace.h" ,
3785+ [ !l4re ] : "sys/quota.h" ,
3786+ [ !l4re ] : "sys/random.h" ,
3787+ [ !l4re ] : "sys/reboot.h" ,
37733788 "sys/resource.h" ,
37743789 "sys/sem.h" ,
3775- "sys/sendfile.h" ,
3790+ [ !l4re ] : "sys/sendfile.h" ,
37763791 "sys/shm.h" ,
3777- "sys/signalfd.h" ,
3792+ [ !l4re ] : "sys/signalfd.h" ,
37783793 "sys/socket.h" ,
37793794 "sys/stat.h" ,
37803795 "sys/statvfs.h" ,
3781- "sys/swap.h" ,
3796+ [ !l4re ] : "sys/swap.h" ,
37823797 "sys/syscall.h" ,
37833798 "sys/time.h" ,
3784- "sys/timerfd.h" ,
3799+ [ !l4re ] : "sys/timerfd.h" ,
37853800 "sys/times.h" ,
3786- "sys/timex.h" ,
3801+ [ !l4re ] : "sys/timex.h" ,
37873802 "sys/types.h" ,
37883803 "sys/uio.h" ,
37893804 "sys/un.h" ,
@@ -3805,12 +3820,12 @@ fn test_linux(target: &str) {
38053820 // ARM: https://bugzilla.redhat.com/show_bug.cgi?id=1116162
38063821 // Also unavailable on gnueabihf with glibc 2.30.
38073822 // https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=6b33f373c7b9199e00ba5fbafd94ac9bfb4337b1
3808- [ ( x86_64 || x86_32 || arm) && !gnueabihf] : "sys/io.h" ,
3823+ [ ( x86_64 || x86_32 || arm) && !gnueabihf && !l4re ] : "sys/io.h" ,
38093824 // `sys/reg.h` is only available on x86 and x86_64
3810- [ x86_64 || x86_32] : "sys/reg.h" ,
3825+ [ ( x86_64 || x86_32) && !l4re ] : "sys/reg.h" ,
38113826 // sysctl system call is deprecated and not available on musl
38123827 // It is also unsupported in x32, deprecated since glibc 2.30:
3813- [ !( x32 || musl || gnu) ] : "sys/sysctl.h" ,
3828+ [ !( x32 || musl || gnu || l4re ) ] : "sys/sysctl.h" ,
38143829 // <execinfo.h> is not supported by musl:
38153830 // https://www.openwall.com/lists/musl/2015/04/09/3
38163831 // <execinfo.h> is not present on uclibc.
@@ -3820,11 +3835,11 @@ fn test_linux(target: &str) {
38203835 // Include linux headers at the end:
38213836 headers ! {
38223837 cfg:
3823- [ loongarch64 || riscv64] : "asm/hwcap.h" ,
3824- "asm/mman.h" ,
3838+ [ ( loongarch64 || riscv64) && !l4re ] : "asm/hwcap.h" ,
3839+ [ !l4re ] : "asm/mman.h" ,
38253840 }
38263841
3827- if !wasm32 {
3842+ if !wasm32 && !l4re {
38283843 headers ! { cfg:
38293844 [ gnu] : "linux/aio_abi.h" ,
38303845 "linux/can.h" ,
@@ -3842,7 +3857,6 @@ fn test_linux(target: &str) {
38423857 "linux/if.h" ,
38433858 "linux/if_addr.h" ,
38443859 "linux/if_alg.h" ,
3845- "linux/if_ether.h" ,
38463860 "linux/if_packet.h" ,
38473861 "linux/if_tun.h" ,
38483862 "linux/if_xdp.h" ,
@@ -3889,7 +3903,6 @@ fn test_linux(target: &str) {
38893903 "linux/wait.h" ,
38903904 "linux/wireless.h" ,
38913905 "sys/fanotify.h" ,
3892- // <sys/auxv.h> is not present on uclibc
38933906 [ !uclibc] : "sys/auxv.h" ,
38943907 [ gnu || musl] : "linux/close_range.h" ,
38953908 }
@@ -3898,7 +3911,7 @@ fn test_linux(target: &str) {
38983911 // note: aio.h must be included before sys/mount.h
38993912 headers ! {
39003913 cfg:
3901- "sys/xattr.h" ,
3914+ [ !l4re ] : "sys/xattr.h" ,
39023915 "sys/sysinfo.h" ,
39033916 // AIO is not supported by uclibc:
39043917 [ !uclibc] : "aio.h" ,
@@ -3911,12 +3924,14 @@ fn test_linux(target: &str) {
39113924 | "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
39123925 | "Elf32_Chdr" | "Elf64_Chdr" => ty. to_string ( ) ,
39133926
3914- "Ioctl" if gnu => "unsigned long" . to_string ( ) ,
3927+ "Ioctl" if gnu || uclibc => "unsigned long" . to_string ( ) ,
39153928 "Ioctl" => "int" . to_string ( ) ,
39163929
39173930 // LFS64 types have been removed in musl 1.2.4+
39183931 "off64_t" if musl => "off_t" . to_string ( ) ,
39193932
3933+ "fsword_t" if uclibc => "__SWORD_TYPE" . to_string ( ) ,
3934+
39203935 // typedefs don't need any keywords
39213936 t if t. ends_with ( "_t" ) => t. to_string ( ) ,
39223937 // put `struct` in front of all structs:.
@@ -4177,6 +4192,12 @@ fn test_linux(target: &str) {
41774192 } ) ;
41784193
41794194 cfg. skip_const ( move |name| {
4195+ // L4Re requires a min stack size of 64k; that isn't defined in uClibc, but
4196+ // somewhere in the core libraries. uClibc wants 16k, but that's not enough.
4197+ if l4re && name == "PTHREAD_STACK_MIN" {
4198+ return true ;
4199+ }
4200+
41804201 if !gnu {
41814202 // Skip definitions from the kernel on non-glibc Linux targets.
41824203 // They're libc-independent, so we only need to check them on one
@@ -4356,7 +4377,7 @@ fn test_linux(target: &str) {
43564377
43574378 // FIXME(musl): on musl the pthread types are defined a little differently
43584379 // - these constants are used by the glibc implementation.
4359- n if musl && n. contains ( "__SIZEOF_PTHREAD" ) => true ,
4380+ n if ( musl || uclibc ) && n. contains ( "__SIZEOF_PTHREAD" ) => true ,
43604381
43614382 // FIXME(linux): It was extended to 4096 since glibc 2.31 (Linux 5.4).
43624383 // We should do so after a while.
@@ -4933,7 +4954,9 @@ fn test_linux(target: &str) {
49334954
49344955 cfg. generate ( src_hotfix_dir ( ) . join ( "lib.rs" ) , "main.rs" ) ;
49354956
4936- test_linux_like_apis ( target) ;
4957+ if !l4re {
4958+ test_linux_like_apis ( target) ;
4959+ }
49374960}
49384961
49394962// This function tests APIs that are incompatible to test when other APIs
0 commit comments