From b36dd197712f2097b1b7aa39949f771c54377e4b Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 27 Jan 2024 21:49:00 +0100 Subject: [PATCH 1/2] Support `-Zbuild-std` --- CHANGELOG.md | 2 ++ src/dependencies.rs | 50 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74e1ea71..fcc6b911 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added * `Text::diff()` creates a text status emitter that does not do full dumps of test stderr/stdout, but only emits the diff of the changes +* Support `-Zbuild-std` by add + * use `DependencyBuilder::build_std` to enable it ### Fixed diff --git a/src/dependencies.rs b/src/dependencies.rs index a146ba15..75d1d40a 100644 --- a/src/dependencies.rs +++ b/src/dependencies.rs @@ -90,6 +90,14 @@ fn build_dependencies_inner( build.arg(format!("--target={target}")); } + if let Some(packages) = &info.build_std { + if packages.is_empty() { + build.arg("-Zbuild-std"); + } else { + build.arg(format!("-Zbuild-std={packages}")); + } + } + // Reusable closure for setting up the environment both for artifact generation and `cargo_metadata` let set_locking = |cmd: &mut Command| { if let OutputConflictHandling::Error = config.output_conflict_handling { @@ -166,7 +174,7 @@ fn build_dependencies_inner( .target .crate_types .iter() - .all(|ctype| !matches!(ctype.as_str(), "proc-macro" | "lib")) + .all(|ctype| !matches!(ctype.as_str(), "proc-macro" | "lib" | "rlib")) { continue; } @@ -174,7 +182,10 @@ fn build_dependencies_inner( import_paths.insert(filename.parent().unwrap().into()); } let package_id = artifact.package_id; - if let Some(prev) = artifacts.insert(package_id.clone(), Ok(artifact.filenames)) { + if let Some(prev) = artifacts.insert( + package_id.clone(), + Ok((artifact.target.name, artifact.filenames)), + ) { artifacts.insert( package_id.clone(), Err(format!( @@ -252,7 +263,7 @@ fn build_dependencies_inner( .unwrap(); // Then go over all of its dependencies - let dependencies = root + let mut dependencies = root .dependencies .iter() .filter(|dep| matches!(dep.kind, DependencyKind::Normal)) @@ -284,7 +295,7 @@ fn build_dependencies_inner( let id = &package.id; // Return the name chosen in `Cargo.toml` and the path to the corresponding artifact match artifacts.remove(id) { - Some(Ok(artifacts)) => Some(Ok((name.replace('-', "_"), artifacts))), + Some(Ok((_, artifacts))) => Some(Ok((name.replace('-', "_"), artifacts))), Some(Err(what)) => Some(Err(Errored { command: Command::new(what), errors: vec![], @@ -306,6 +317,28 @@ fn build_dependencies_inner( .collect::, Errored>>()?; let import_paths = import_paths.into_iter().collect(); let import_libs = import_libs.into_iter().collect(); + + if info.build_std.is_some() { + let mut build_std_crates = HashSet::new(); + build_std_crates.insert("core"); + build_std_crates.insert("alloc"); + build_std_crates.insert("proc_macro"); + build_std_crates.insert("panic_unwind"); + build_std_crates.insert("compiler_builtins"); + build_std_crates.insert("std"); + build_std_crates.insert("test"); + build_std_crates.insert("panic_abort"); + + for (name, artifacts) in artifacts + .into_iter() + .filter_map(|(_, artifacts)| artifacts.ok()) + { + if build_std_crates.remove(name.as_str()) { + dependencies.push((format!("noprelude:{name}"), artifacts)); + } + } + } + return Ok(Dependencies { dependencies, import_paths, @@ -329,6 +362,9 @@ pub struct DependencyBuilder { /// The command to run can be changed from `cargo` to any custom command to build the /// dependencies in `crate_manifest_path`. pub program: CommandBuilder, + /// Build with [`build-std`](https://doc.rust-lang.org/1.78.0/cargo/reference/unstable.html#build-std), + /// which requires the nightly toolchain. The [`String`] can contain the standard library crates to build. + pub build_std: Option, } impl Default for DependencyBuilder { @@ -336,6 +372,7 @@ impl Default for DependencyBuilder { Self { crate_manifest_path: PathBuf::from("Cargo.toml"), program: CommandBuilder::cargo(), + build_std: None, } } } @@ -381,6 +418,11 @@ pub fn build_dependencies( ) -> Result, Errored> { let dependencies = build_dependencies_inner(config, info)?; let mut args = vec![]; + + if info.build_std.is_some() { + args.push("-Zunstable-options".into()); + } + for (name, artifacts) in dependencies.dependencies { for dependency in artifacts { args.push("--extern".into()); From e1d2c697cda6f1e6e1ceedd7e78fe63b8d340145 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 11 Jun 2024 15:56:28 +0200 Subject: [PATCH 2/2] Add `-Zbuild-std` test --- .github/workflows/rust.yml | 25 +++++++++++++++++++++++++ Cargo.toml | 4 ++++ tests/build_std.rs | 21 +++++++++++++++++++++ tests/build_std/test.rs | 0 4 files changed, 50 insertions(+) create mode 100644 tests/build_std.rs create mode 100644 tests/build_std/test.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 208f4bbe..7d9e93ba 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -60,3 +60,28 @@ jobs: run: cargo test --verbose - name: Test no-rustc mode run: cargo check --no-default-features + + build-std: + strategy: + matrix: + include: + - os: ubuntu-latest + host_target: x86_64-unknown-linux-gnu + - os: macos-latest + host_target: x86_64-apple-darwin + - os: windows-latest + host_target: i686-pc-windows-msvc + runs-on: ${{ matrix.os }} + # Run tests under a directory with a space in it to double check the windows path heuristic + defaults: + run: + working-directory: "dir with spaces/build std" + steps: + - uses: actions/checkout@v4 + with: + path: "dir with spaces/build std" + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - name: Run build-std test + run: cargo test --verbose --test build_std diff --git a/Cargo.toml b/Cargo.toml index 45a133d8..75980a40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,10 @@ features = ["capture-spantrace"] name = "integration" harness = false +[[test]] +name = "build_std" +test = false + [features] default = ["rustc"] rustc = [] diff --git a/tests/build_std.rs b/tests/build_std.rs new file mode 100644 index 00000000..2109b1e7 --- /dev/null +++ b/tests/build_std.rs @@ -0,0 +1,21 @@ +use ui_test::dependencies::DependencyBuilder; +use ui_test::spanned::Spanned; +use ui_test::Config; + +#[test] +fn test() { + let mut config = Config::rustc("tests/build_std"); + let revisioned = config.comment_defaults.base(); + + revisioned.exit_status = Spanned::dummy(0).into(); + revisioned.require_annotations = Spanned::dummy(false).into(); + revisioned.set_custom( + "dependencies", + DependencyBuilder { + build_std: Some(String::new()), + ..DependencyBuilder::default() + }, + ); + + ui_test::run_tests(config).unwrap(); +} diff --git a/tests/build_std/test.rs b/tests/build_std/test.rs new file mode 100644 index 00000000..e69de29b