Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
# Here we use the latest stable Rust toolchain already installed by GitHub
# Ideally we should run it for every target, but we cannot rely on unstable toolchains
# due to Clippy not being consistent between them.
- run: cargo clippy --workspace --exclude libc-test --exclude ctest-test --all-targets -- -D warnings
- run: cargo clippy --locked --workspace --exclude libc-test --exclude ctest-test --all-targets -- -D warnings

# This runs `cargo build --target ...` for all T1 and T2 targets`
verify_build:
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ Common sources include:
* RedoxOS: <https://gitlab.redox-os.org/redox-os/relibc>
* Uclibc: <https://github.com/wbx-github/uclibc-ng> (mirror),
<https://git.uclibc-ng.org/git/uclibc-ng.git> (original)
* WASI: <https://github.com/WebAssembly/wasi-libc>
* Windows GNU: <https://github.com/mingw-w64/mingw-w64> (unofficial mirror),
<https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/> (original)
* Windows MSVC: <https://github.com/microsoft/win32metadata>
Expand Down
35 changes: 30 additions & 5 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ enum Cfg {
LibcPauthtest,

EmscriptenOldStatAbi,
EmscriptenFsblkcntIs32bit,
EmscriptenSigsetLarge,
EmscriptenNfdsIsULong,

/// Should be enabled by users if esp-idf (>=6.0) is build with picolibc instead of newlib. Not
/// set by `libc` itself.
Expand Down Expand Up @@ -63,6 +66,9 @@ enum Cfg {
const ALLOWED_CFGS: &[Cfg] = &[
Cfg::LibcDenyWarnings,
Cfg::EmscriptenOldStatAbi,
Cfg::EmscriptenFsblkcntIs32bit,
Cfg::EmscriptenSigsetLarge,
Cfg::EmscriptenNfdsIsULong,
Cfg::EspidfPicolibc,
Cfg::EspidfTime32,
Cfg::Freebsd10,
Expand All @@ -88,6 +94,9 @@ impl fmt::Display for Cfg {
f.write_str(match self {
Cfg::LibcDenyWarnings => "libc_deny_warnings",
Cfg::EmscriptenOldStatAbi => "emscripten_old_stat_abi",
Cfg::EmscriptenFsblkcntIs32bit => "emscripten_fsblkcnt_is_32bit",
Cfg::EmscriptenSigsetLarge => "emscripten_sigset_large",
Cfg::EmscriptenNfdsIsULong => "emscripten_nfds_is_ulong",
Cfg::EspidfPicolibc => "espidf_picolibc",
Cfg::EspidfTime32 => "espidf_time32",
Cfg::Freebsd10 => "freebsd10",
Expand Down Expand Up @@ -214,10 +223,23 @@ fn main() {
}

if target_os == "emscripten" {
match emcc_version_code() {
Some(v) if (v < 30142) => cfgs.push(Cfg::EmscriptenOldStatAbi),
// Non-Emscripten or version >= 3.1.42.
_ => (),
if let Some(v) = emcc_version_code() {
// 3.1.42
if v < 30142 {
cfgs.push(Cfg::EmscriptenOldStatAbi);
}
// 4.0.12
if v < 40012 {
cfgs.push(Cfg::EmscriptenFsblkcntIs32bit);
}
// 5.0.5
if v < 50005 {
cfgs.push(Cfg::EmscriptenSigsetLarge);
}
// 6.0.1
if v < 60001 {
cfgs.push(Cfg::EmscriptenNfdsIsULong);
}
}
}

Expand Down Expand Up @@ -452,7 +474,10 @@ fn validate_cfg(list: &[Cfg], target_env: &str, target_os: &str, target_ptr_widt
Cfg::EspidfPicolibc => (),
Cfg::EspidfTime32 => (),

Cfg::EmscriptenOldStatAbi => {
Cfg::EmscriptenOldStatAbi
| Cfg::EmscriptenFsblkcntIs32bit
| Cfg::EmscriptenSigsetLarge
| Cfg::EmscriptenNfdsIsULong => {
assert_eq!(
target_os, "emscripten",
"{cfg:?} set on non-freebsd platform"
Expand Down
2 changes: 1 addition & 1 deletion ci/emscripten.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -eux

# Note: keep in sync with:
# https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md#requirements
emsdk_version=3.1.68
emsdk_version=6.0.11

git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
cd /emsdk-portable
Expand Down
4 changes: 3 additions & 1 deletion ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ uname -a
dpkg -l | grep libc- || true

cmd="cargo test --target $target ${LIBC_CI_ZBUILD_STD+"-Zbuild-std"}"
doc_cmd="cargo doc --target $target ${LIBC_CI_ZBUILD_STD+"-Zbuild-std"} --no-deps --workspace"
test_flags="--skip check_style"

# Run tests in the `libc` crate
Expand All @@ -36,6 +37,7 @@ esac
if [ "${LIBC_CI_ZBUILD_STD:-}" ]; then
# ctest test infrastructure has no support for -Zbuild-std
cmd="$cmd --exclude ctest --exclude ctest-test"
doc_cmd="$doc_cmd --exclude ctest --exclude ctest-test"
fi

env="$(rustc --print cfg --target "$target" | sed -n 's/target_env="\(.*\)"/\1/p')"
Expand All @@ -48,7 +50,7 @@ $cmd -- $test_flags
# shellcheck disable=SC2086
$cmd --features extra_traits -- $test_flags

cargo doc --target "$target" --workspace --no-deps
$doc_cmd

# On relevant platforms, also test with our optional settings

Expand Down
109 changes: 29 additions & 80 deletions libc-test/build/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ mod target;
use std::env;
use std::env::VarError;
use std::io::Write;
use std::process::{
Command,
Stdio,
};
use std::process::Stdio;
use std::sync::LazyLock;

use regex::Regex;
Expand Down Expand Up @@ -1609,13 +1606,7 @@ fn test_dragonflybsd(t: &Target) {
let mut cfg = ctest_cfg();
cfg.flag("-Wno-deprecated-declarations");

let dragonfly_version = if let Ok(version) = env::var("RUST_LIBC_UNSTABLE_DRAGONFLY_VERSION") {
let vers = parse_dragonfly_version(&version).unwrap();
println!("cargo:warning=setting DragonFly version to {vers}");
vers
} else {
which_dragonfly().unwrap_or(600_200)
};
let dragonfly = VERSIONS.dragonfly.unwrap();

headers!(
cfg,
Expand Down Expand Up @@ -1836,11 +1827,7 @@ fn test_dragonflybsd(t: &Target) {
| "PROC_PDEATHSIG_CTL"
| "PROC_PDEATHSIG_STATUS"
| "KERN_STATIC_TLS_EXTRA"
| "KERN_MAXID"
if dragonfly_version < 600_000 =>
{
true
}
| "KERN_MAXID" => dragonfly < (6, 0),

// weird signed extension or something like that?
"MS_NOUSER" => true,
Expand All @@ -1859,20 +1846,17 @@ fn test_dragonflybsd(t: &Target) {
match func.ident() {
// FIXME: https://github.com/rust-lang/libc/issues/1272
"execv" | "execve" | "execvp" | "fexecve" => true,
"getrlimit" | "getrlimit64" | // non-int in 1st arg
"setrlimit" | "setrlimit64" | // non-int in 1st arg
"prlimit" | "prlimit64" // non-int in 2nd arg
=> true,
// non-int in 1st arg
"getrlimit" | "getrlimit64" | "setrlimit" | "setrlimit64" => true,
// non-int in 2nd arg
"prlimit" | "prlimit64" => true,

// These are exposed unconditionally by libc, but older DragonFly
// headers cannot validate them.
"clock_nanosleep" | "pthread_getname_np" | "pthread_setname_np"
if dragonfly_version < 600_000 => true,
"pthread_getaffinity_np" | "pthread_setaffinity_np" if dragonfly_version < 600_000 => {
true
},
"fdatasync" | "getentropy" | "posix_fallocate" if dragonfly_version < 600_200 => true,
"malloc_usable_size" if dragonfly_version < 600_400 => true,
"clock_nanosleep" | "pthread_getname_np" | "pthread_setname_np" => dragonfly < (6, 0),
"pthread_getaffinity_np" | "pthread_setaffinity_np" => dragonfly < (6, 0),
"fdatasync" | "getentropy" | "posix_fallocate" => dragonfly < (6, 0),
"malloc_usable_size" => dragonfly < (6, 0),
_ => false,
}
});
Expand All @@ -1895,7 +1879,7 @@ fn test_dragonflybsd(t: &Target) {
// structs.
"termios2" => true,

"ip_mreqn" if dragonfly_version < 600_000 => true,
"ip_mreqn" => dragonfly < (6, 0),

_ => false,
}
Expand Down Expand Up @@ -1936,39 +1920,6 @@ fn test_dragonflybsd(t: &Target) {
ctest::generate_test(&mut cfg, "../src/lib.rs", "ctest_output.rs").unwrap();
}

fn parse_dragonfly_version(version: &str) -> Option<u32> {
let version = version.trim();

if let Ok(version) = version.parse::<u32>() {
// DragonFly's __DragonFly_version uses major * 100_000 + minor * 100.
// Accept compact test override spellings like 58, 60, 62, and 602.
return Some(match version {
0..=9 => version * 100_000,
10..=99 => (version / 10) * 100_000 + (version % 10) * 100,
100..=999 => (version / 100) * 100_000 + (version % 100) * 100,
_ => version,
});
}

let mut pieces = version.split(['.', '-']);
let major = pieces.next()?.parse::<u32>().ok()?;
let minor = pieces.next()?.parse::<u32>().ok()?;
Some(major * 100_000 + minor * 100)
}

fn which_dragonfly() -> Option<u32> {
if env::var("CARGO_CFG_TARGET_OS").ok()?.as_str() != "dragonfly" {
return None;
}

if try_command_output("uname", &["-s"])?.trim() != "DragonFly" {
return None;
}

let stdout = try_command_output("uname", &["-r"])?;
parse_dragonfly_version(stdout.trim())
}

fn test_wasi(t: &Target) {
assert!(t.wasi());
let p2 = t.wasip2();
Expand Down Expand Up @@ -2303,8 +2254,6 @@ fn test_android(t: &Target) {
// These are tested as part of the linux_fcntl tests since there are
// header conflicts when including them with all the other structs.
"termios2" => true,
// 'private' type
"prop_info" => true,

// These are tested in the `linux_elf.rs` file.
"Elf64_Phdr" | "Elf32_Phdr" => true,
Expand All @@ -2318,7 +2267,7 @@ fn test_android(t: &Target) {
"sockaddr_vm" => true,

// Extern types
"DIR" | "FILE" | "fpos_t" | "timezone" => true,
"DIR" | "FILE" | "fpos_t" | "timezone" | "prop_info" => true,

_ => false,
}
Expand Down Expand Up @@ -2859,6 +2808,10 @@ fn test_freebsd(t: &Target) {
// be stable, and probably shouldn't be bound by libc at all.
"RLIM_NLIMITS" => true,

// This constant was never intended to be stable, probably shouldn't have been bound by
// libc at all, and was changed for FreeBSD 15.2 (git 2bacbbecb16 and 547751e4efcef)
"NOTE_PCTRLMASK" => true,

// This symbol changed in FreeBSD 14 (git 051e7d78b03), but the new
// version should be safe to use on older releases.
"IFCAP_CANTCHANGE" => true,
Expand Down Expand Up @@ -6362,6 +6315,7 @@ static VERSIONS: LazyLock<Versions> = LazyLock::new(Versions::init_from_cc);
struct Versions {
linux: Option<(u32, u32)>,
glibc: Option<(u32, u32)>,
dragonfly: Option<(u32, u32)>,
freebsd: Option<(u32, u32)>,
openbsd: Option<(u32, u32)>,
netbsd: Option<(u32, u32)>,
Expand Down Expand Up @@ -6405,10 +6359,12 @@ impl Versions {
#include "android/api-level.h"
#endif

#if defined(__FreeBSD__) \
#if defined(__DragonFly__) \
|| defined(__FreeBSD__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__)
/* FreeBSD: __FreeBSD_version (MMmmRxx string, e.g. 1600018)
/* DragonFlyBSD: __DragonFly_version (Mmmmpp string, e.g. 600401)
* FreeBSD: __FreeBSD_version (MMmmRxx string, e.g. 1600018)
* NetBSD: __NetBSD_Version__ (MMmmrrpp00 string, e.g. 1001000000)
* OpenBSD: OpenBSD (release date, e.g. 202510) and OpenBSDM_m (e.g. OpenBSD7_8)
*/
Expand Down Expand Up @@ -6496,6 +6452,13 @@ impl Versions {
// and is set on watchOS, tvOS and visionOS too).
ret.apple = Some((major, minor));
}
"__DragonFly_version" => {
// DragonFly's __DragonFly_version uses major * 100_000 + minor * 100.
let version = value.parse::<u32>().unwrap();
let major = version / 100_000;
let minor = (version % 100_000) / 100;
ret.dragonfly = Some((major, minor));
}
"__FreeBSD_version" => {
// Format: MmmRxx where M is major (possibly multi-digit), mm is minor, R
// indicates release status, xx is some sequence.
Expand Down Expand Up @@ -6549,20 +6512,6 @@ impl Versions {
}
}

/// Attempt to execute a command and collect its output, If the command fails for whatever
/// reason, return `None`.
fn try_command_output(cmd: &str, args: &[&str]) -> Option<String> {
let output = Command::new(cmd).args(args).output().ok()?;

if !output.status.success() {
return None;
}

let res = String::from_utf8(output.stdout)
.unwrap_or_else(|e| panic!("command {cmd} returned non-UTF-8 output: {e}"));
Some(res)
}

/// Return true if the env is set to a value other than `0`.
fn env_flag(key: &str) -> bool {
match env::var(key) {
Expand Down
4 changes: 2 additions & 2 deletions libc-test/semver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ ensure that APIs aren't removed between libc releases.

## File order

Files are including in the following order:
Files are included in the following order:

* Family, e.g. `unix.txt`. NOTE: Windows is skipped here and includes as OS name
* Family, e.g. `unix.txt`. NOTE: Windows is skipped here and included as OS
below.
* Vendor, e.g. `apple.txt`. This allows us to have a single file with system
calls shared between multiple OSs, e.g. `ios.txt`, `macos.txt` share the same
Expand Down
2 changes: 2 additions & 0 deletions libc-test/semver/apple.txt
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ F_ALLOCATEPERSIST
F_BARRIERFSYNC
F_FREEZE_FS
F_FULLFSYNC
F_GETNOSIGPIPE
F_GETOWN
F_GETPATH
F_GETPATH_NOFIRMLINK
Expand All @@ -410,6 +411,7 @@ F_PUNCHHOLE
F_RDADVISE
F_RDAHEAD
F_RDLCK
F_SETNOSIGPIPE
F_SETOWN
F_SPECULATIVE_READ
F_TEST
Expand Down
Loading
Loading