Skip to content

Commit 5e025e0

Browse files
committed
Separate L4Re from Linux code, add aarch64 and enable tests
The L4Re code was previously attached to the Linux code which was not correct in many ways. This commit separates the L4Re code and enables the libc-tests and includes the fixes for the failing tests. Aarch64 is added as a second supported architecture (more to come).
1 parent e84e2da commit 5e025e0

File tree

18 files changed

+6913
-2738
lines changed

18 files changed

+6913
-2738
lines changed

ctest/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,8 @@ fn default_cfg(target: &str) -> Vec<(String, Option<String>)> {
11001100
("hurd", "unix", "gnu")
11011101
} else if target.contains("cygwin") {
11021102
("cygwin", "unix", "")
1103+
} else if target.contains("l4re-uclibc") {
1104+
("l4re", "unix", "uclibc")
11031105
} else {
11041106
panic!("unknown os/family: {target}")
11051107
};

libc-test/build.rs

Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
@@ -3653,18 +3655,26 @@ fn config_gnu_bits(target: &str, cfg: &mut ctest::TestGenerator) {
36533655
}
36543656

36553657
fn test_linux(target: &str) {
3656-
assert!(target.contains("linux"));
3658+
assert!(target.contains("linux") || target.contains("l4re"));
3659+
3660+
// target_os
3661+
let linux = target.contains("linux");
3662+
let l4re = target.contains("l4re");
36573663

36583664
// target_env
36593665
let gnu = target.contains("gnu");
36603666
let musl = target.contains("musl") || target.contains("ohos");
36613667
let uclibc = target.contains("uclibc");
36623668

3663-
match (gnu, musl, uclibc) {
3664-
(true, false, false) => (),
3665-
(false, true, false) => (),
3666-
(false, false, true) => (),
3667-
(_, _, _) => panic!("linux target lib is gnu: {gnu}, musl: {musl}, uclibc: {uclibc}"),
3669+
match (linux, gnu, musl, uclibc) {
3670+
(true, true, false, false) => (),
3671+
(true, false, true, false) => (),
3672+
(true, false, false, true) => (),
3673+
(false, false, false, true) => (),
3674+
(_, _, _, _) => panic!(
3675+
"{} target lib is gnu: {gnu}, musl: {musl}, uclibc: {uclibc}",
3676+
if linux { "linux" } else { "l4re" }
3677+
),
36683678
}
36693679

36703680
let arm = target.contains("arm");
@@ -3696,8 +3706,10 @@ fn test_linux(target: &str) {
36963706
// deprecated since glibc >= 2.29. This allows Rust binaries to link against
36973707
// glibc versions older than 2.29.
36983708
cfg.define("__GLIBC_USE_DEPRECATED_SCANF", None);
3699-
37003709
config_gnu_bits(target, &mut cfg);
3710+
if l4re {
3711+
cfg.flag("-Wno-unused-function");
3712+
}
37013713

37023714
headers! { cfg:
37033715
"ctype.h",
@@ -3716,11 +3728,12 @@ fn test_linux(target: &str) {
37163728
"libgen.h",
37173729
"limits.h",
37183730
"link.h",
3719-
"linux/sysctl.h",
3731+
[uclibc]: "linux/if_ether.h",
3732+
[!l4re]: "linux/sysctl.h",
37203733
"locale.h",
37213734
"malloc.h",
37223735
"mntent.h",
3723-
"mqueue.h",
3736+
[!l4re]: "mqueue.h",
37243737
"net/ethernet.h",
37253738
"net/if.h",
37263739
"net/if_arp.h",
@@ -3730,6 +3743,7 @@ fn test_linux(target: &str) {
37303743
"netinet/ip.h",
37313744
"netinet/tcp.h",
37323745
"netinet/udp.h",
3746+
[l4re]: "netpacket/packet.h",
37333747
"poll.h",
37343748
"pthread.h",
37353749
"pty.h",
@@ -3740,43 +3754,44 @@ fn test_linux(target: &str) {
37403754
"semaphore.h",
37413755
"shadow.h",
37423756
"signal.h",
3743-
"spawn.h",
3744-
"stddef.h",
3757+
[!l4re]: "spawn.h",
3758+
[!l4re]: "stddef.h",
37453759
"stdint.h",
37463760
"stdio.h",
37473761
"stdlib.h",
37483762
"string.h",
3749-
"sys/epoll.h",
3750-
"sys/eventfd.h",
3763+
[l4re]: "sys/auxv.h",
3764+
[!l4re]: "sys/epoll.h",
3765+
[!l4re]: "sys/eventfd.h",
37513766
"sys/file.h",
3752-
"sys/fsuid.h",
3753-
"sys/klog.h",
3754-
"sys/inotify.h",
3767+
[!l4re]: "sys/fsuid.h",
3768+
[!l4re]: "sys/klog.h",
3769+
[!l4re]: "sys/inotify.h",
37553770
"sys/ioctl.h",
37563771
"sys/ipc.h",
37573772
"sys/mman.h",
37583773
"sys/mount.h",
3759-
"sys/msg.h",
3760-
"sys/personality.h",
3774+
[!l4re]: "sys/msg.h",
3775+
[!l4re]: "sys/personality.h",
37613776
"sys/prctl.h",
3762-
"sys/ptrace.h",
3763-
"sys/quota.h",
3764-
"sys/random.h",
3765-
"sys/reboot.h",
3777+
[!l4re]: "sys/ptrace.h",
3778+
[!l4re]: "sys/quota.h",
3779+
[!l4re]: "sys/random.h",
3780+
[!l4re]: "sys/reboot.h",
37663781
"sys/resource.h",
37673782
"sys/sem.h",
3768-
"sys/sendfile.h",
3783+
[!l4re]: "sys/sendfile.h",
37693784
"sys/shm.h",
3770-
"sys/signalfd.h",
3785+
[!l4re]: "sys/signalfd.h",
37713786
"sys/socket.h",
37723787
"sys/stat.h",
37733788
"sys/statvfs.h",
3774-
"sys/swap.h",
3789+
[!l4re]: "sys/swap.h",
37753790
"sys/syscall.h",
37763791
"sys/time.h",
3777-
"sys/timerfd.h",
3792+
[!l4re]: "sys/timerfd.h",
37783793
"sys/times.h",
3779-
"sys/timex.h",
3794+
[!l4re]: "sys/timex.h",
37803795
"sys/types.h",
37813796
"sys/uio.h",
37823797
"sys/un.h",
@@ -3798,12 +3813,12 @@ fn test_linux(target: &str) {
37983813
// ARM: https://bugzilla.redhat.com/show_bug.cgi?id=1116162
37993814
// Also unavailable on gnueabihf with glibc 2.30.
38003815
// https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=6b33f373c7b9199e00ba5fbafd94ac9bfb4337b1
3801-
[(x86_64 || x86_32 || arm) && !gnueabihf]: "sys/io.h",
3816+
[(x86_64 || x86_32 || arm) && !gnueabihf && !l4re]: "sys/io.h",
38023817
// `sys/reg.h` is only available on x86 and x86_64
3803-
[x86_64 || x86_32]: "sys/reg.h",
3818+
[(x86_64 || x86_32) && !l4re]: "sys/reg.h",
38043819
// sysctl system call is deprecated and not available on musl
38053820
// It is also unsupported in x32, deprecated since glibc 2.30:
3806-
[!(x32 || musl || gnu)]: "sys/sysctl.h",
3821+
[!(x32 || musl || gnu || l4re)]: "sys/sysctl.h",
38073822
// <execinfo.h> is not supported by musl:
38083823
// https://www.openwall.com/lists/musl/2015/04/09/3
38093824
// <execinfo.h> is not present on uclibc.
@@ -3813,11 +3828,11 @@ fn test_linux(target: &str) {
38133828
// Include linux headers at the end:
38143829
headers! {
38153830
cfg:
3816-
[loongarch64 || riscv64]: "asm/hwcap.h",
3817-
"asm/mman.h",
3831+
[(loongarch64 || riscv64) && !l4re]: "asm/hwcap.h",
3832+
[!l4re]: "asm/mman.h",
38183833
}
38193834

3820-
if !wasm32 {
3835+
if !wasm32 && !l4re {
38213836
headers! { cfg:
38223837
[gnu]: "linux/aio_abi.h",
38233838
"linux/can.h",
@@ -3835,7 +3850,6 @@ fn test_linux(target: &str) {
38353850
"linux/if.h",
38363851
"linux/if_addr.h",
38373852
"linux/if_alg.h",
3838-
"linux/if_ether.h",
38393853
"linux/if_packet.h",
38403854
"linux/if_tun.h",
38413855
"linux/if_xdp.h",
@@ -3881,7 +3895,6 @@ fn test_linux(target: &str) {
38813895
"linux/wait.h",
38823896
"linux/wireless.h",
38833897
"sys/fanotify.h",
3884-
// <sys/auxv.h> is not present on uclibc
38853898
[!uclibc]: "sys/auxv.h",
38863899
[gnu || musl]: "linux/close_range.h",
38873900
}
@@ -3890,7 +3903,7 @@ fn test_linux(target: &str) {
38903903
// note: aio.h must be included before sys/mount.h
38913904
headers! {
38923905
cfg:
3893-
"sys/xattr.h",
3906+
[!l4re]: "sys/xattr.h",
38943907
"sys/sysinfo.h",
38953908
// AIO is not supported by uclibc:
38963909
[!uclibc]: "aio.h",
@@ -3903,12 +3916,14 @@ fn test_linux(target: &str) {
39033916
| "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
39043917
| "Elf32_Chdr" | "Elf64_Chdr" => ty.to_string(),
39053918

3906-
"Ioctl" if gnu => "unsigned long".to_string(),
3919+
"Ioctl" if gnu || uclibc => "unsigned long".to_string(),
39073920
"Ioctl" => "int".to_string(),
39083921

39093922
// LFS64 types have been removed in musl 1.2.4+
39103923
"off64_t" if musl => "off_t".to_string(),
39113924

3925+
"fsword_t" if uclibc => "__SWORD_TYPE".to_string(),
3926+
39123927
// typedefs don't need any keywords
39133928
t if t.ends_with("_t") => t.to_string(),
39143929
// put `struct` in front of all structs:.
@@ -4169,6 +4184,12 @@ fn test_linux(target: &str) {
41694184
});
41704185

41714186
cfg.skip_const(move |name| {
4187+
// L4Re requires a min stack size of 64k; that isn't defined in uClibc, but
4188+
// somewhere in the core libraries. uClibc wants 16k, but that's not enough.
4189+
if l4re && name == "PTHREAD_STACK_MIN" {
4190+
return true;
4191+
}
4192+
41724193
if !gnu {
41734194
// Skip definitions from the kernel on non-glibc Linux targets.
41744195
// They're libc-independent, so we only need to check them on one
@@ -4343,7 +4364,7 @@ fn test_linux(target: &str) {
43434364

43444365
// FIXME(musl): on musl the pthread types are defined a little differently
43454366
// - these constants are used by the glibc implementation.
4346-
n if musl && n.contains("__SIZEOF_PTHREAD") => true,
4367+
n if (musl || uclibc) && n.contains("__SIZEOF_PTHREAD") => true,
43474368

43484369
// FIXME(linux): It was extended to 4096 since glibc 2.31 (Linux 5.4).
43494370
// We should do so after a while.
@@ -4920,7 +4941,9 @@ fn test_linux(target: &str) {
49204941

49214942
cfg.generate(src_hotfix_dir().join("lib.rs"), "main.rs");
49224943

4923-
test_linux_like_apis(target);
4944+
if !l4re {
4945+
test_linux_like_apis(target);
4946+
}
49244947
}
49254948

49264949
// This function tests APIs that are incompatible to test when other APIs

0 commit comments

Comments
 (0)