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
14 changes: 13 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
rust:
- nightly
# Check a ~3 months old nightly as "oldest supported version"
- nightly-2025-05-01
- nightly-2026-01-01
# We want to run all of the above on Linux, macOS, windows-msvc, windows-gnu.
# The semantics of combining `include` with other things in GHA are very strange
# so this seems like the best way of doing that.
Expand Down Expand Up @@ -51,6 +51,18 @@ jobs:
- name: Run tests
run: cargo test --locked --target ${{ matrix.target }}

build-dir-new-layout:
name: Test Suite (build-dir-new-layout)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
components: rust-src
- name: Run tests
run: CARGO_UNSTABLE_BUILD_DIR_NEW_LAYOUT=true cargo test --locked

check:
name: Checks
runs-on: ubuntu-latest
Expand Down
47 changes: 36 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,17 +531,17 @@ impl<'a> SysrootBuilder<'a> {
fs::create_dir(&staging_lib_dir).context("failed to create staging/lib dir")?;
let out_dir = build_target_dir
.join(&target_name)
.join(DEFAULT_SYSROOT_PROFILE)
.join("deps");
for entry in fs::read_dir(&out_dir).context("failed to read cargo out dir")? {
let entry = entry.context("failed to read cargo out dir entry")?;
assert!(
entry.file_type().unwrap().is_file(),
"cargo out dir must not contain directories"
);
let entry = entry.path();
fs::copy(&entry, staging_lib_dir.join(entry.file_name().unwrap()))
.context("failed to copy cargo out file")?;
.join(DEFAULT_SYSROOT_PROFILE);
if out_dir.join("deps").exists() {
// Old build dir layout: $out/deps
copy_files(&out_dir.join("deps"), &staging_lib_dir)
.context("failed to copy cargo out dir (old layout)")?;
} else {
// New build dir layout: $out/build/*/*/out.
for_each_dir(&out_dir.join("build"), |dir| {
for_each_dir(dir, |dir| copy_files(&dir.join("out"), &staging_lib_dir))
})
.context("failed to copy cargo out dir (new layout)")?;
}

// Write the hash file (into the staging dir).
Expand All @@ -564,6 +564,31 @@ impl<'a> SysrootBuilder<'a> {
}
}

/// Coopy all files in `from` to `to`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: coopy

fn copy_files(from: &Path, to: &Path) -> Result<()> {
for entry in fs::read_dir(from)? {
let entry = entry?;
assert!(
entry.file_type()?.is_file(),
"cargo out dir must not contain directories"
);
fs::copy(&entry.path(), to.join(entry.file_name()))?;
}
Ok(())
}

/// Invoke the closure for each directory inside `path`.
fn for_each_dir(path: &Path, f: impl Fn(&Path) -> Result<()>) -> Result<()> {
for entry in fs::read_dir(path)? {
let entry = entry?;
if !entry.file_type()?.is_dir() {
continue;
}
f(&entry.path())?;
}
Ok(())
}

/// Collect the patches from the sysroot's workspace `Cargo.toml`.
fn extract_patches(src_dir: &Path) -> Table {
// Assume no patch is needed if the workspace Cargo.toml doesn't exist
Expand Down
28 changes: 7 additions & 21 deletions tests/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(clippy::useless_format)]

use std::fs;
use std::process::{self, Command};

Expand All @@ -17,9 +19,10 @@ fn run(cmd: &mut Command) {

fn build_sysroot(b: SysrootBuilder) {
let src_dir = rustc_sysroot_src(Command::new("rustc")).unwrap();
b.cargo(Command::new("cargo"))
.build_from_source(&src_dir)
.unwrap();
let mut cargo = Command::new("cargo");
// Cargo complains about unknown `-Z` flags but not about unknown env vars. :)
cargo.env("CARGO_UNSTABLE_JSON_TARGET_SPEC", "true");
b.cargo(cargo).build_from_source(&src_dir).unwrap();
}

fn test_sysroot_build(target: &str, mode: BuildMode, rustc_version: &VersionMeta) {
Expand Down Expand Up @@ -91,28 +94,11 @@ fn no_std() {

#[test]
fn json_target() {
// The syntax for `target-pointer-width` changed from `"64"`` to `64`. Figure out which one
// this rustc needs...
let sample_json = Command::new("rustc")
.args([
"-Zunstable-options",
"--print=target-spec-json",
"--target=x86_64-unknown-none",
])
.output()
.unwrap()
.stdout;
let sample_json = String::from_utf8(sample_json).unwrap();
let ptr_width = if sample_json.contains(r#""target-pointer-width": 64"#) {
"64"
} else {
r#""64""#
};
let target = format!(
r#"{{
"llvm-target": "x86_64-unknown-none",
"target-endian": "little",
"target-pointer-width": {ptr_width},
"target-pointer-width": 64,
"target-c-int-width": 32,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
Expand Down
Loading