@@ -64,6 +64,7 @@ fn do_ctest() {
6464 t if t. contains ( "emscripten" ) => test_emscripten ( t) ,
6565 t if t. contains ( "freebsd" ) => test_freebsd ( t) ,
6666 t if t. contains ( "haiku" ) => test_haiku ( t) ,
67+ t if t. contains ( "l4re" ) => test_linux ( t) ,
6768 t if t. contains ( "linux" ) => test_linux ( t) ,
6869 t if t. contains ( "netbsd" ) => test_netbsd ( t) ,
6970 t if t. contains ( "openbsd" ) => test_openbsd ( t) ,
@@ -115,9 +116,10 @@ fn do_semver() {
115116 // NOTE: Android doesn't include the unix file (or the Linux file) because
116117 // there are some many definitions missing it's actually easier just to
117118 // maintain a file for Android.
118- // NOTE: AIX doesn't include the unix file because there are definitions
119- // missing on AIX. It is easier to maintain a file for AIX.
120- if family != os && !matches ! ( os. as_str( ) , "android" | "aix" ) && os != "vxworks" {
119+ // NOTE: AIX and L4Re do not include the unix file because there are
120+ // definitions missing on these systems. It is easier to maintain separate
121+ // files for them.
122+ if family != os && !matches ! ( os. as_str( ) , "android" | "aix" | "l4re" ) && os != "vxworks" {
121123 process_semver_file ( & mut output, & mut semver_root, & family) ;
122124 }
123125 // We don't do semver for unknown targets.
@@ -3805,19 +3807,28 @@ fn config_gnu_bits(target: &str, cfg: &mut ctest::TestGenerator) {
38053807 }
38063808}
38073809
3810+ // This also covers the L4Re targets since they have a similar API surface
38083811fn test_linux ( target : & str ) {
3809- assert ! ( target. contains( "linux" ) ) ;
3812+ assert ! ( target. contains( "linux" ) || target. contains( "l4re" ) ) ;
3813+
3814+ // target_os
3815+ let linux = target. contains ( "linux" ) ;
3816+ let l4re = target. contains ( "l4re" ) ;
38103817
38113818 // target_env
38123819 let gnu = target. contains ( "gnu" ) ;
38133820 let musl = target. contains ( "musl" ) || target. contains ( "ohos" ) ;
38143821 let uclibc = target. contains ( "uclibc" ) ;
38153822
3816- match ( gnu, musl, uclibc) {
3817- ( true , false , false ) => ( ) ,
3818- ( false , true , false ) => ( ) ,
3819- ( false , false , true ) => ( ) ,
3820- ( _, _, _) => panic ! ( "linux target lib is gnu: {gnu}, musl: {musl}, uclibc: {uclibc}" ) ,
3823+ match ( l4re, gnu, musl, uclibc) {
3824+ ( false , true , false , false ) => ( ) ,
3825+ ( false , false , true , false ) => ( ) ,
3826+ ( false , false , false , true ) => ( ) ,
3827+ ( true , false , false , true ) => ( ) ,
3828+ ( _, _, _, _) => panic ! (
3829+ "{} target lib is gnu: {gnu}, musl: {musl}, uclibc: {uclibc}" ,
3830+ if linux { "linux" } else { "l4re" }
3831+ ) ,
38213832 }
38223833
38233834 let arm = target. contains ( "arm" ) ;
@@ -3855,6 +3866,11 @@ fn test_linux(target: &str) {
38553866 . define ( "__GLIBC_USE_DEPRECATED_SCANF" , None ) ;
38563867
38573868 config_gnu_bits ( target, & mut cfg) ;
3869+ // The L4Re libc headers contain some L4Re helper functions which are not needed for the libc
3870+ // interface and must not be added to the libc crate
3871+ if l4re {
3872+ cfg. flag ( "-Wno-unused-function" ) ;
3873+ }
38583874
38593875 headers ! (
38603876 cfg,
@@ -3874,11 +3890,11 @@ fn test_linux(target: &str) {
38743890 "libgen.h" ,
38753891 "limits.h" ,
38763892 "link.h" ,
3877- "linux/sysctl.h" ,
3893+ ( !l4re , "linux/sysctl.h" ) ,
38783894 "locale.h" ,
38793895 "malloc.h" ,
38803896 "mntent.h" ,
3881- "mqueue.h" ,
3897+ ( !l4re , "mqueue.h" ) ,
38823898 "net/ethernet.h" ,
38833899 "net/if.h" ,
38843900 "net/if_arp.h" ,
@@ -3888,6 +3904,7 @@ fn test_linux(target: &str) {
38883904 "netinet/ip.h" ,
38893905 "netinet/tcp.h" ,
38903906 "netinet/udp.h" ,
3907+ ( l4re, "netpacket/packet.h" ) ,
38913908 "poll.h" ,
38923909 "pthread.h" ,
38933910 "pty.h" ,
@@ -3898,43 +3915,44 @@ fn test_linux(target: &str) {
38983915 "semaphore.h" ,
38993916 "shadow.h" ,
39003917 "signal.h" ,
3901- "spawn.h" ,
3902- "stddef.h" ,
3918+ ( !l4re , "spawn.h" ) ,
3919+ ( !l4re , "stddef.h" ) ,
39033920 "stdint.h" ,
39043921 "stdio.h" ,
39053922 "stdlib.h" ,
39063923 "string.h" ,
3907- "sys/epoll.h" ,
3908- "sys/eventfd.h" ,
3924+ ( l4re, "sys/auxv.h" ) ,
3925+ ( !l4re, "sys/epoll.h" ) ,
3926+ ( !l4re, "sys/eventfd.h" ) ,
39093927 "sys/file.h" ,
3910- "sys/fsuid.h" ,
3911- "sys/klog.h" ,
3912- "sys/inotify.h" ,
3928+ ( !l4re , "sys/fsuid.h" ) ,
3929+ ( !l4re , "sys/klog.h" ) ,
3930+ ( !l4re , "sys/inotify.h" ) ,
39133931 "sys/ioctl.h" ,
39143932 "sys/ipc.h" ,
39153933 "sys/mman.h" ,
39163934 "sys/mount.h" ,
3917- "sys/msg.h" ,
3918- "sys/personality.h" ,
3935+ ( !l4re , "sys/msg.h" ) ,
3936+ ( !l4re , "sys/personality.h" ) ,
39193937 "sys/prctl.h" ,
3920- "sys/ptrace.h" ,
3921- "sys/quota.h" ,
3922- "sys/random.h" ,
3923- "sys/reboot.h" ,
3938+ ( !l4re , "sys/ptrace.h" ) ,
3939+ ( !l4re , "sys/quota.h" ) ,
3940+ ( !l4re , "sys/random.h" ) ,
3941+ ( !l4re , "sys/reboot.h" ) ,
39243942 "sys/resource.h" ,
39253943 "sys/sem.h" ,
3926- "sys/sendfile.h" ,
3944+ ( !l4re , "sys/sendfile.h" ) ,
39273945 "sys/shm.h" ,
3928- "sys/signalfd.h" ,
3946+ ( !l4re , "sys/signalfd.h" ) ,
39293947 "sys/socket.h" ,
39303948 "sys/stat.h" ,
39313949 "sys/statvfs.h" ,
3932- "sys/swap.h" ,
3950+ ( !l4re , "sys/swap.h" ) ,
39333951 "sys/syscall.h" ,
39343952 "sys/time.h" ,
3935- "sys/timerfd.h" ,
3953+ ( !l4re , "sys/timerfd.h" ) ,
39363954 "sys/times.h" ,
3937- "sys/timex.h" ,
3955+ ( !l4re , "sys/timex.h" ) ,
39383956 "sys/types.h" ,
39393957 "sys/uio.h" ,
39403958 "sys/un.h" ,
@@ -3956,22 +3974,26 @@ fn test_linux(target: &str) {
39563974 // ARM: https://bugzilla.redhat.com/show_bug.cgi?id=1116162
39573975 // Also unavailable on gnueabihf with glibc 2.30.
39583976 // https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=6b33f373c7b9199e00ba5fbafd94ac9bfb4337b1
3959- ( ( x86_64 || x86_32 || arm) && !gnueabihf, "sys/io.h" ) ,
3977+ ( ( x86_64 || x86_32 || arm) && !gnueabihf && !l4re , "sys/io.h" ) ,
39603978 // `sys/reg.h` is only available on x86 and x86_64
3961- ( x86_64 || x86_32, "sys/reg.h" ) ,
3979+ ( ( x86_64 || x86_32) && !l4re , "sys/reg.h" ) ,
39623980 // sysctl system call is deprecated and not available on musl
39633981 // It is also unsupported in x32, deprecated since glibc 2.30:
3964- ( !( x32 || musl || gnu) , "sys/sysctl.h" ) ,
3982+ ( !( x32 || musl || gnu || l4re ) , "sys/sysctl.h" ) ,
39653983 // <execinfo.h> is not supported by musl:
39663984 // https://www.openwall.com/lists/musl/2015/04/09/3
39673985 // <execinfo.h> is not present on uclibc.
39683986 ( !( musl || uclibc) , "execinfo.h" ) ,
39693987 ) ;
39703988
39713989 // Include linux headers at the end:
3972- headers ! ( cfg, ( loongarch64 || riscv64, "asm/hwcap.h" ) , "asm/mman.h" , ) ;
3990+ headers ! (
3991+ cfg,
3992+ ( ( loongarch64 || riscv64) && !l4re, "asm/hwcap.h" ) ,
3993+ ( !l4re, "asm/mman.h" ) ,
3994+ ) ;
39733995
3974- if !wasm32 {
3996+ if !wasm32 && !l4re {
39753997 headers ! (
39763998 cfg,
39773999 ( gnu, "linux/aio_abi.h" ) ,
@@ -4047,7 +4069,7 @@ fn test_linux(target: &str) {
40474069 // note: aio.h must be included before sys/mount.h
40484070 headers ! (
40494071 cfg,
4050- "sys/xattr.h" ,
4072+ ( !l4re , "sys/xattr.h" ) ,
40514073 "sys/sysinfo.h" ,
40524074 // AIO is not supported by uclibc:
40534075 ( !uclibc, "aio.h" ) ,
@@ -4077,10 +4099,11 @@ fn test_linux(target: &str) {
40774099
40784100 cfg. rename_type ( move |ty| {
40794101 match ty {
4080- "Ioctl" if gnu => Some ( "unsigned long" . to_string ( ) ) ,
4102+ "Ioctl" if gnu || uclibc => Some ( "unsigned long" . to_string ( ) ) ,
40814103 "Ioctl" => Some ( "int" . to_string ( ) ) ,
40824104 // LFS64 types have been removed in musl 1.2.4+
40834105 "off64_t" if musl => Some ( "off_t" . to_string ( ) ) ,
4106+ "fsword_t" if uclibc => Some ( "__SWORD_TYPE" . to_string ( ) ) ,
40844107 _ => None ,
40854108 }
40864109 } ) ;
@@ -4277,6 +4300,13 @@ fn test_linux(target: &str) {
42774300
42784301 cfg. skip_const ( move |constant| {
42794302 let name = constant. ident ( ) ;
4303+
4304+ // L4Re requires a min stack size of 64k; that isn't defined in uClibc, but
4305+ // somewhere in the core libraries. uClibc wants 16k, but that's not enough.
4306+ if l4re && name == "PTHREAD_STACK_MIN" {
4307+ return true ;
4308+ }
4309+
42804310 if !gnu {
42814311 // Skip definitions from the kernel on non-glibc Linux targets.
42824312 // They're libc-independent, so we only need to check them on one
@@ -4426,7 +4456,7 @@ fn test_linux(target: &str) {
44264456
44274457 // FIXME(musl): on musl the pthread types are defined a little differently
44284458 // - these constants are used by the glibc implementation.
4429- n if musl && n. contains ( "__SIZEOF_PTHREAD" ) => true ,
4459+ n if ( musl || uclibc ) && n. contains ( "__SIZEOF_PTHREAD" ) => true ,
44304460
44314461 // FIXME(linux): It was extended to 4096 since glibc 2.31 (Linux 5.4).
44324462 // We should do so after a while.
@@ -4859,6 +4889,8 @@ fn test_linux(target: &str) {
48594889 ( "bcm_msg_head" , "frames" ) => true ,
48604890 // FAM
48614891 ( "af_alg_iv" , "iv" ) => true ,
4892+ // FIXME(ctest): ctest does not translate the rust code which computes the padding size
4893+ ( "pthread_cond_t" , "__padding" ) if l4re => true ,
48624894 _ => false ,
48634895 }
48644896 } ) ;
@@ -4986,7 +5018,9 @@ fn test_linux(target: &str) {
49865018
49875019 ctest:: generate_test ( & mut cfg, "../src/lib.rs" , "ctest_output.rs" ) . unwrap ( ) ;
49885020
4989- test_linux_like_apis ( target) ;
5021+ if !l4re {
5022+ test_linux_like_apis ( target) ;
5023+ }
49905024}
49915025
49925026// This function tests APIs that are incompatible to test when other APIs
0 commit comments