Skip to content
Draft
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
13 changes: 13 additions & 0 deletions ci/buildroot_defconfigs/armv7_unknown_linux_uclibceabihf.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BR2_arm=y
BR2_cortex_a9=y
BR2_ARM_ENABLE_VFP=y
BR2_TOOLCHAIN_BUILDROOT_UCLIBC=y
BR2_TOOLCHAIN_BUILDROOT_LOCALE=y
BR2_PTHREAD_DEBUG=y
BR2_BINUTILS_VERSION_2_44_X=y
BR2_GCC_VERSION_15_X=y
BR2_INIT_NONE=y
BR2_SYSTEM_BIN_SH_NONE=y
# BR2_PACKAGE_BUSYBOX is not set
BR2_PACKAGE_READLINE=y
# BR2_TARGET_ROOTFS_TAR is not set
26 changes: 17 additions & 9 deletions ci/docker/armv7-unknown-linux-uclibceabihf/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
FROM ubuntu:23.10
FROM ubuntu:25.04

# FIXME(time): we are using an EOL release because 24.04 changes to 64-bit time
RUN sed -i -E 's/(archive|security)\.ubuntu\.com/old-releases.ubuntu.com/g' \
/etc/apt/sources.list && \
apt-get update && apt-get install -y --no-install-recommends \
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
file \
Expand All @@ -12,14 +9,25 @@ RUN sed -i -E 's/(archive|security)\.ubuntu\.com/old-releases.ubuntu.com/g' \
patch \
qemu-system-arm \
qemu-user \
bzip2 \
gzip \
make \
wget \
cpio \
unzip \
rsync \
bc \
g++ \
perl \
xz-utils

ARG TEST_UCLIBC_TIME64
COPY install-uclibc.sh /
RUN /install-uclibc.sh "$TEST_UCLIBC_TIME64"
COPY buildroot_defconfigs/armv7_unknown_linux_uclibceabihf.config /
RUN /install-uclibc.sh /armv7_unknown_linux_uclibceabihf.config "$TEST_UCLIBC_TIME64"

ENV PATH=$PATH:/rust/bin:/toolchain/bin \
STAGING_DIR=/toolchain/armv7-buildroot-linux-uclibceabihf/sysroot \
ENV PATH=$PATH:/rust/bin:/buildroot/output/host/bin \
STAGING_DIR=/buildroot/output/host/armv7-buildroot-linux-uclibceabihf/sysroot \
CC_armv7_unknown_linux_uclibceabihf=arm-buildroot-linux-uclibcgnueabihf-gcc \
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_LINKER=arm-buildroot-linux-uclibcgnueabihf-gcc \
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_RUNNER="qemu-arm -L /toolchain/arm-buildroot-linux-uclibcgnueabihf/sysroot/"
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_RUNNER="qemu-arm -L /buildroot/output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/"
25 changes: 12 additions & 13 deletions ci/install-uclibc.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
#!/bin/bash
#
# Installs the appropriate uclibc toolchain into /toolchain
# Builds a buildroot uclibc toolchain into /buildroot/output/host/
#
# usage: install-uclibc.sh BUILDROOT_DEFCONFIG USE_TIME64

set -eux

time64="$1"

if [ "${time64:-0}" != "0" ]; then
version='bleeding-edge-2025.08-1'
else
version='bleeding-edge-2024.02-1' # last version with 32-bit time_t
fi

mkdir /toolchain
defconfig="$1"
# shellcheck disable=SC2034
time64="$2" # TODO: honor this flag, adjusting UCLIBC_USE_TIME64 in config

curl --retry 5 -L "https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--${version}.tar.bz2" |
tar xjf - -C /toolchain --strip-components=1
mkdir /buildroot
BR_URL=https://buildroot.org/downloads/buildroot-2026.05.tar.xz
curl --retry 5 -L "$BR_URL" | tar xJf - -C /buildroot --strip-components=1

/toolchain/relocate-sdk.sh
cd /buildroot
make defconfig "BR2_DEFCONFIG=$defconfig"
make
2 changes: 1 addition & 1 deletion ci/run-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ run() {

if [ -n "${TEST_UCLIBC_TIME64:-}" ]; then
build_args+=("--build-arg=TEST_UCLIBC_TIME64=1")
export RUSTFLAGS="$RUSTFLAGS --cfg=libc_unstable_uclibc_time64"
export RUSTFLAGS="${RUSTFLAGS:-} --cfg=libc_unstable_uclibc_time64"
fi

# use -f so we can use ci/ as build context
Expand Down
5 changes: 5 additions & 0 deletions ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ case "$target" in
powerpc64le*musl) cmd="$cmd --exclude ctest --exclude ctest-test --exclude ctest-next" ;;
esac

if [ "${LIBC_CI_ZBUILD_STD:-}" ]; then
# ctest test infrastructure has no support for -Zbuild-std
cmd="$cmd --exclude ctest --exclude ctest-test"
fi

env="$(rustc --print cfg --target "$target" | sed -n 's/target_env="\(.*\)"/\1/p')"
bits="$(rustc --print cfg --target "$target" | sed -n 's/target_pointer_width="\(.*\)"/\1/p')"

Expand Down
2 changes: 1 addition & 1 deletion ctest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ cc = "1.2.43"
proc-macro2 = { version = "1.0.103", features = ["span-locations"] }
quote = "1.0.41"
syn = { version = "2.0.108", features = ["full", "visit", "extra-traits"] }
tempfile = "3.23.0"
thiserror = "2.0.17"

[lints]
workspace = true

[dev-dependencies]
pretty_assertions = "1.4.1"
tempfile = "3.23.0"
31 changes: 29 additions & 2 deletions ctest/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use syn::visit::Visit;
use thiserror::Error;

use crate::ffi_items::FfiItems;
use crate::macro_expansion::expand_with_args;
use crate::template::{
CTestTemplate,
RustTestTemplate,
Expand All @@ -32,7 +33,6 @@ use crate::{
Type,
Union,
VolatileItemKind,
expand,
get_build_target,
};

Expand Down Expand Up @@ -78,6 +78,10 @@ pub struct TestGenerator {
cfg: Vec<(String, Option<String>)>,
/// A list of functions that remaps names used in the tests.
mapped_names: Vec<MappedName>,
/// Extra command line args to pass to cargo when generating macro expansions.
macro_expansion_cargo_args: Vec<String>,
/// Crate name to use when performing macro expansion.
crate_name: Option<String>,
/// The programming language to generate tests in.
pub(crate) language: Language,
/// A list of functions that determine what items to skip all tests for.
Expand Down Expand Up @@ -723,6 +727,22 @@ impl TestGenerator {
self
}

/// Configures extra arguments to be passed to cargo during macro expansion.
/// This can be used, for example, to pass `-Zbuild-std`` if required.
pub fn macro_expansion_cargo_args_mut(&mut self) -> &mut Vec<String> {
&mut self.macro_expansion_cargo_args
}

/// Configures the crate name which should be used during macro expansion.
///
/// If the tested crate uses `#![crate_name = "..."]`, this must be called with the
/// same name. Otherwise, there will be an error about `--crate-name` not
/// matching.
pub fn crate_name(&mut self, name: String) -> &mut Self {
self.crate_name = Some(name);
self
}

/// Configures whether tests for the type of a field is skipped or not.
///
/// The closure is given a Rust struct as well as a field within that
Expand Down Expand Up @@ -1087,7 +1107,14 @@ impl TestGenerator {
crate_path: impl AsRef<Path>,
output_file_path: impl AsRef<Path>,
) -> Result<PathBuf, GenerationError> {
let expanded = expand(&crate_path, &self.cfg, get_build_target(self)?).map_err(|e| {
let expanded = expand_with_args(
&crate_path,
&self.cfg,
get_build_target(self)?,
self.crate_name.as_deref(),
&self.macro_expansion_cargo_args,
)
.map_err(|e| {
GenerationError::MacroExpansion(crate_path.as_ref().to_path_buf(), e.to_string())
})?;
let ast = syn::parse_file(&expanded)
Expand Down
63 changes: 55 additions & 8 deletions ctest/src/macro_expansion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::env;
use std::fs::canonicalize;
use std::path::Path;
use std::process::Command;
Expand All @@ -14,19 +13,63 @@ pub fn expand<P: AsRef<Path>>(
cfg: &[(String, Option<String>)],
target: String,
) -> Result<String> {
let rustc = env::var("RUSTC").unwrap_or_else(|_| String::from("rustc"));
expand_with_args(crate_path, cfg, target, None, &[])
}

/// Extension of `expand` which allows a crate_name override for
/// libc and other clients which require crate_name to match the
/// original crate's name.
pub(crate) fn expand_with_args<P: AsRef<Path>>(
crate_path: P,
cfg: &[(String, Option<String>)],
target: String,
crate_name: Option<&str>,
extra_cargo_args: &[String],
) -> Result<String> {
let dir = tempfile::tempdir()?;

// make a Cargo.toml pointing to the crate path
let cargo_toml_path = dir.path().join("Cargo.toml");
let crate_name = crate_name.unwrap_or("ctest-expansion-tmp");
// FIXME(#5238): allow building using an existing manifest
let cargo_toml = format!(
r#"
[package]
name = '''{crate_name}''' # Needs to match #![crate_name = "..."] if it exists.
edition = '''{EDITION}'''
[lib]
path = '''{}'''
[lints.rust]
unexpected_cfgs = "allow"
"#,
canonicalize(crate_path)?.display()
);
std::fs::write(cargo_toml_path, cargo_toml)?;

let mut cmd = Command::new(rustc);
let mut cmd = Command::new(std::env::var("CARGO").unwrap_or("cargo".into()));
cmd.env("RUSTC_BOOTSTRAP", "1")
.arg("-Zunpretty=expanded")
.arg("--edition")
.arg(EDITION) // By default, -Zunpretty=expanded uses 2015 edition.
.arg(canonicalize(crate_path)?);
.current_dir(dir.path())
.arg("rustc")
.arg("--lib")
.arg("--profile")
.arg("check")
.args(extra_cargo_args);

// In order to avoid warnings causing failures here when the
// environment's RUSTFLAGS contains -Dwarnings (or similar),
// we will clear RUSTFLAGS.
cmd.env_remove("RUSTFLAGS");

// set an independent target dir so we don't deadlock on the cargo build lock.
cmd.arg("--target-dir").arg(dir.path().join("target"));

if !target.is_empty() {
cmd.arg("--target").arg(target);
}

cmd.arg("--");
cmd.arg("-Zunpretty=expanded");

// `libc` uses non standard cfg flags as well, which have to be manually expanded.
for (k, v) in cfg {
match v {
Expand All @@ -39,7 +82,11 @@ pub fn expand<P: AsRef<Path>>(

if !output.status.success() {
let stderr = std::str::from_utf8(&output.stderr)?;
return Err(format!("macro expansion failed with {}: {}", output.status, stderr).into());
return Err(format!(
"macro expansion failed with {}: {}, {:?}",
output.status, stderr, cmd
)
.into());
}

let expanded = std::str::from_utf8(&output.stdout)?.to_string();
Expand Down
Loading
Loading