Skip to content

Commit 0840ee1

Browse files
committed
Add a FreeBSD 12 build job and test FreeBSD12 APIs
This commits adds a second FreeBSD 12 build job, and splits the implementation of the FreeBSD module into two modules, one for FreeBSD 11, and one for FreeBSD 12. The FreeBSD 11 module is compiled always by default, and is mostly forward compatible with FreeBSD 12 systems. The FreeBSD 12 module is only built for now in libc's CI, and uses FreeBSD 12 data types and APIs, linking to symbols that are only available in FreeBSD 12. Basically, when LIBC_CI env variable is defined, and the host system is a FreeBSD 12 system, then the FreeBSD 12 module is automatically built and tested. Conditional compilation is done using a `cfg(freebsd12)` flag. This commit also re-enables many tests, and documents why some remain disabled.
1 parent 13fa8b2 commit 0840ee1

File tree

16 files changed

+636
-364
lines changed

16 files changed

+636
-364
lines changed

.cirrus.yml

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
freebsd_instance:
2-
image: freebsd-11-1-release-amd64
3-
41
task:
5-
name: stable x86_64-unknown-freebsd
2+
name: stable x86_64-unknown-freebsd-11
3+
freebsd_instance:
4+
image: freebsd-11-2-release-amd64
65
setup_script:
76
- pkg install -y curl
87
- curl https://sh.rustup.rs -sSf --output rustup.sh
@@ -12,9 +11,11 @@ task:
1211
test_script:
1312
- . $HOME/.cargo/env
1413
- sh ci/run.sh x86_64-unknown-freebsd
15-
14+
1615
task:
17-
name: nightly x86_64-unknown-freebsd
16+
name: nightly x86_64-unknown-freebsd-12
17+
freebsd_instance:
18+
image: freebsd-12-0-release-amd64
1819
setup_script:
1920
- pkg install -y curl
2021
- curl https://sh.rustup.rs -sSf --output rustup.sh

build.rs

+23
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ fn main() {
99
std::env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok();
1010
let align_cargo_feature = std::env::var("CARGO_FEATURE_ALIGN").is_ok();
1111

12+
if std::env::var("LIBC_CI").is_ok() {
13+
if let Some(12) = which_freebsd() {
14+
println!("cargo:rustc-cfg=freebsd12");
15+
}
16+
}
17+
1218
// Rust >= 1.15 supports private module use:
1319
if rustc_minor_ver >= 15 || rustc_dep_of_std {
1420
println!("cargo:rustc-cfg=libc_priv_mod_use");
@@ -63,3 +69,20 @@ fn rustc_minor_version() -> Option<u32> {
6369

6470
otry!(pieces.next()).parse().ok()
6571
}
72+
73+
fn which_freebsd() -> Option<i32> {
74+
let output = std::process::Command::new("freebsd-version")
75+
.output()
76+
.ok()?;
77+
if !output.status.success() {
78+
return None;
79+
}
80+
81+
let stdout = String::from_utf8(output.stdout).ok()?;
82+
83+
match &stdout {
84+
s if s.starts_with("11") => Some(11),
85+
s if s.starts_with("12") => Some(12),
86+
_ => None,
87+
}
88+
}

ci/run.sh

+5-3
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,12 @@ if [ "$TARGET" = "x86_64-unknown-linux-gnux32" ]; then
8787
opt="--release"
8888
fi
8989

90-
cargo test $opt --no-default-features --manifest-path libc-test/Cargo.toml \
90+
export LIBC_CI=1
91+
92+
cargo test -vv $opt --no-default-features --manifest-path libc-test/Cargo.toml \
9193
--target "${TARGET}"
9294

93-
cargo test $opt --manifest-path libc-test/Cargo.toml --target "${TARGET}"
95+
cargo test -vv $opt --manifest-path libc-test/Cargo.toml --target "${TARGET}"
9496

95-
cargo test $opt --features extra_traits --manifest-path libc-test/Cargo.toml \
97+
cargo test -vv $opt --features extra_traits --manifest-path libc-test/Cargo.toml \
9698
--target "${TARGET}"

libc-test/build.rs

+65-129
Original file line numberDiff line numberDiff line change
@@ -1444,11 +1444,19 @@ fn test_android(target: &str) {
14441444

14451445
fn test_freebsd(target: &str) {
14461446
assert!(target.contains("freebsd"));
1447-
let x86 = target.contains("i686") || target.contains("x86_64");
1448-
14491447
let mut cfg = ctest::TestGenerator::new();
1448+
1449+
let freebsd_ver = which_freebsd();
1450+
1451+
if let Some(12) = freebsd_ver {
1452+
// If the host is FreeBSD 12, run FreeBSD 12 tests
1453+
cfg.cfg("freebsd12", None);
1454+
}
1455+
14501456
// Required for `getline`:
14511457
cfg.define("_WITH_GETLINE", None);
1458+
// Required for making freebsd11_stat available in the headers
1459+
cfg.define("_WANT_FREEBSD11_STAT", None);
14521460

14531461
headers! { cfg:
14541462
"aio.h",
@@ -1530,12 +1538,16 @@ fn test_freebsd(target: &str) {
15301538
// Just pass all these through, no need for a "struct" prefix
15311539
"FILE" | "fd_set" | "Dl_info" | "DIR" => ty.to_string(),
15321540

1541+
// FIXME: https://github.com/rust-lang/libc/issues/1273
15331542
"sighandler_t" => "sig_t".to_string(),
15341543

15351544
t if is_union => format!("union {}", t),
15361545

15371546
t if t.ends_with("_t") => t.to_string(),
15381547

1548+
// sigval is a struct in Rust, but a union in C:
1549+
"sigval" => format!("union sigval"),
1550+
15391551
// put `struct` in front of all structs:.
15401552
t if is_struct => format!("struct {}", t),
15411553

@@ -1557,169 +1569,76 @@ fn test_freebsd(target: &str) {
15571569
}
15581570
});
15591571

1560-
cfg.skip_struct(move |ty| {
1561-
match ty {
1562-
// This is actually a union, not a struct
1563-
// FIXME: still required?
1564-
"sigval" => true,
1565-
1566-
_ => false,
1567-
}
1568-
});
1569-
1570-
cfg.skip_signededness(move |c| {
1571-
match c {
1572-
// FIXME: still required?
1573-
"LARGE_INTEGER" | "float" | "double" => true,
1574-
// FIXME: still required?
1575-
n if n.starts_with("pthread") => true,
1576-
// sem_t is a struct or pointer
1577-
// FIXME: still required?
1578-
"sem_t" => true,
1579-
// mqd_t is a pointer on FreeBSD
1580-
// FIXME: still required?
1581-
"mqd_t" => true,
1582-
1583-
_ => false,
1584-
}
1585-
});
1586-
15871572
cfg.skip_const(move |name| {
15881573
match name {
1589-
// FIXME: still required?
1590-
"SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
1574+
// These constants were introduced in FreeBSD 12:
1575+
"SF_USER_READAHEAD"
1576+
| "EVFILT_EMPTY"
1577+
| "SO_REUSEPORT_LB"
1578+
| "IP_ORIGDSTADDR"
1579+
| "IP_RECVORIGDSTADDR"
1580+
| "IPV6_ORIGDSTADDR"
1581+
| "IPV6_RECVORIGDSTADDR"
1582+
if Some(12) != freebsd_ver =>
1583+
{
1584+
true
1585+
}
15911586

1587+
// FIXME: There are deprecated - remove in a couple of releases.
15921588
// These constants were removed in FreeBSD 11 (svn r273250) but will
15931589
// still be accepted and ignored at runtime.
1594-
"MAP_RENAME" | "MAP_NORESERVE" => true,
1590+
"MAP_RENAME" | "MAP_NORESERVE" if Some(10) != freebsd_ver => true,
15951591

1592+
// FIXME: There are deprecated - remove in a couple of releases.
15961593
// These constants were removed in FreeBSD 11 (svn r262489),
15971594
// and they've never had any legitimate use outside of the
15981595
// base system anyway.
15991596
"CTL_MAXID" | "KERN_MAXID" | "HW_MAXID" | "NET_MAXID"
16001597
| "USER_MAXID" => true,
16011598

1602-
// These constants were added in FreeBSD 11
1603-
// FIXME: still required?
1604-
"EVFILT_PROCDESC" | "EVFILT_SENDFILE" | "EVFILT_EMPTY"
1605-
| "PD_CLOEXEC" | "PD_ALLOWED_AT_FORK" => true,
1606-
1607-
// These constants were added in FreeBSD 12
1608-
// FIXME: still required?
1609-
"SF_USER_READAHEAD" | "SO_REUSEPORT_LB" => true,
1610-
1611-
// These constants are tested in a separate test program generated
1612-
// below because there are header conflicts if we try to include the
1613-
// headers that define them here.
1614-
// FIXME: still required?
1615-
"F_CANCELLK" | "F_ADD_SEALS" | "F_GET_SEALS" => true,
1616-
// FIXME: still required?
1617-
"F_SEAL_SEAL" | "F_SEAL_SHRINK" | "F_SEAL_GROW"
1618-
| "F_SEAL_WRITE" => true,
1619-
// FIXME: still required?
1620-
"BOTHER" => true,
1621-
1622-
// MFD_HUGETLB is not available in some older libc versions on the
1623-
// CI builders. On the x86_64 and i686 builders it seems to be
1624-
// available for all targets, so at least test it there.
1625-
// FIXME: still required?
1626-
"MFD_HUGETLB" if !x86 => true,
1627-
1628-
// These change all the time from release to release of linux
1629-
// distros, let's just not bother trying to verify them. They
1630-
// shouldn't be used in code anyway...
1631-
// FIXME: still required?
1632-
"AF_MAX" | "PF_MAX" => true,
1633-
1634-
// FreeBSD 12 required, but CI has FreeBSD 11.
1635-
// FIXME: still required?
1636-
"IP_ORIGDSTADDR"
1637-
| "IP_RECVORIGDSTADDR"
1638-
| "IPV6_ORIGDSTADDR"
1639-
| "IPV6_RECVORIGDSTADDR" => true,
1640-
16411599
_ => false,
16421600
}
16431601
});
16441602

16451603
cfg.skip_fn(move |name| {
16461604
// skip those that are manually verified
16471605
match name {
1648-
// FIXME: still required?
1649-
"execv" | // crazy stuff with const/mut
1650-
"execve" |
1651-
"execvp" |
1652-
"execvpe" |
1653-
"fexecve" => true,
1606+
// FIXME: https://github.com/rust-lang/libc/issues/1272
1607+
"execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true,
16541608

16551609
// The `uname` function in freebsd is now an inline wrapper that
16561610
// delegates to another, but the symbol still exists, so don't check
16571611
// the symbol.
1658-
// FIXME: still required?
16591612
"uname" => true,
16601613

1661-
// FIXME: need to upgrade FreeBSD version; see https://github.com/rust-lang/libc/issues/938
1662-
// FIXME: still required?
1663-
"setgrent" => true,
1664-
1665-
// aio_waitcomplete's return type changed between FreeBSD 10 and 11.
1666-
// FIXME: still required?
1667-
"aio_waitcomplete" => true,
1668-
1669-
// lio_listio confuses the checker, probably because one of its
1670-
// arguments is an array
1671-
// FIXME: still required?
1614+
// FIXME: Our API is unsound. The Rust API allows aliasing
1615+
// pointers, but the C API requires pointers not to alias.
1616+
// We should probably be at least using `&`/`&mut` here, see:
1617+
// https://github.com/gnzlbg/ctest/issues/68
16721618
"lio_listio" => true,
16731619

1674-
// Definition of those functions as changed since unified headers from NDK r14b
1675-
// These changes imply some API breaking changes but are still ABI compatible.
1676-
// We can wait for the next major release to be compliant with the new API.
1677-
// FIXME: unskip these for next major release
1678-
// FIXME: still required ?
1679-
"strerror_r" | "madvise" | "msync" | "mprotect" | "recvfrom" | "getpriority" |
1680-
16811620
_ => false,
16821621
}
16831622
});
16841623

1685-
cfg.skip_field_type(move |struct_, field| {
1686-
// This is a weird union, don't check the type.
1687-
// FIXME: still required?
1688-
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
1689-
// FIXME: still required?
1690-
// sighandler_t type is super weird
1691-
(struct_ == "sigaction" && field == "sa_sigaction") ||
1692-
// FIXME: still required?
1693-
// sigval is actually a union, but we pretend it's a struct
1694-
(struct_ == "sigevent" && field == "sigev_value") ||
1695-
// aio_buf is "volatile void*" and Rust doesn't understand volatile
1696-
// FIXME: still required?
1697-
(struct_ == "aiocb" && field == "aio_buf") ||
1698-
// stack_t.ss_sp's type changed from FreeBSD 10 to 11 in svn r294930
1699-
// FIXME: still required?
1700-
(struct_ == "stack_t" && field == "ss_sp")
1624+
cfg.volatile_item(|i| {
1625+
use ctest::VolatileItemKind::*;
1626+
match i {
1627+
// aio_buf is a volatile void** but since we cannot express that in
1628+
// Rust types, we have to explicitly tell the checker about it here:
1629+
StructField(ref n, ref f) if n == "aiocb" && f == "aio_buf" => {
1630+
true
1631+
}
1632+
_ => false,
1633+
}
17011634
});
17021635

17031636
cfg.skip_field(move |struct_, field| {
1704-
// this is actually a union on linux, so we can't represent it well and
1705-
// just insert some padding.
1706-
// FIXME: still required?
1707-
(struct_ == "siginfo_t" && field == "_pad") ||
1708-
// sigev_notify_thread_id is actually part of a sigev_un union
1709-
// FIXME: still required?
1710-
(struct_ == "sigevent" && field == "sigev_notify_thread_id") ||
1711-
// signalfd had SIGSYS fields added in Linux 4.18, but no libc release has them yet.
1712-
// FIXME: still required?
1713-
(struct_ == "signalfd_siginfo" && (field == "ssi_addr_lsb" ||
1714-
field == "_pad2" ||
1715-
field == "ssi_syscall" ||
1716-
field == "ssi_call_addr" ||
1717-
field == "ssi_arch"))
1637+
// FIXME: `sa_sigaction` has type `sighandler_t` but that type is
1638+
// incorrect, see: https://github.com/rust-lang/libc/issues/1359
1639+
(struct_ == "sigaction" && field == "sa_sigaction")
17181640
});
17191641

1720-
// FIXME: remove
1721-
cfg.fn_cname(move |name, _cname| name.to_string());
1722-
17231642
cfg.generate("../src/lib.rs", "main.rs");
17241643
}
17251644

@@ -2686,3 +2605,20 @@ fn test_linux_termios2(target: &str) {
26862605
});
26872606
cfg.generate("../src/lib.rs", "linux_fcntl.rs");
26882607
}
2608+
2609+
fn which_freebsd() -> Option<i32> {
2610+
let output = std::process::Command::new("freebsd-version")
2611+
.output()
2612+
.ok()?;
2613+
if !output.status.success() {
2614+
return None;
2615+
}
2616+
2617+
let stdout = String::from_utf8(output.stdout).ok()?;
2618+
2619+
match &stdout {
2620+
s if s.starts_with("11") => Some(11),
2621+
s if s.starts_with("12") => Some(12),
2622+
_ => None,
2623+
}
2624+
}

src/unix/bsd/apple/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3018,6 +3018,7 @@ f! {
30183018
}
30193019

30203020
extern {
3021+
pub fn setgrent();
30213022
#[doc(hidden)]
30223023
#[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.5")]
30233024
#[link_name = "daemon$1050"]

src/unix/bsd/freebsdlike/dragonfly/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub type dev_t = u32;
12
pub type c_char = i8;
23
pub type clock_t = u64;
34
pub type ino_t = u64;
@@ -27,6 +28,15 @@ impl ::Clone for sem {
2728
}
2829

2930
s! {
31+
pub struct kevent {
32+
pub ident: ::uintptr_t,
33+
pub filter: ::c_short,
34+
pub flags: ::c_ushort,
35+
pub fflags: ::c_uint,
36+
pub data: ::intptr_t,
37+
pub udata: *mut ::c_void,
38+
}
39+
3040
pub struct exit_status {
3141
pub e_termination: u16,
3242
pub e_exit: u16
@@ -1008,6 +1018,7 @@ f! {
10081018
}
10091019

10101020
extern {
1021+
pub fn setgrent();
10111022
pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int)
10121023
-> ::c_int;
10131024
pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int;

0 commit comments

Comments
 (0)