From 4a88f924c6899ff08960cb2df9446c23dad7dbb4 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 8 Jan 2025 16:18:01 -0500 Subject: [PATCH 1/3] test: extract checking installed target to a function --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/cargo-test-support/Cargo.toml | 2 +- .../cargo-test-support/src/cross_compile.rs | 30 +++++++++++++++++++ tests/testsuite/standard_lib.rs | 27 +++++------------ 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f79a3d70f26..5003bee8c13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -456,7 +456,7 @@ version = "0.4.0" [[package]] name = "cargo-test-support" -version = "0.7.0" +version = "0.7.1" dependencies = [ "anstream", "anstyle", diff --git a/Cargo.toml b/Cargo.toml index c021bb3537d..16907c6f41e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ cargo-credential-macos-keychain = { version = "0.4.7", path = "credential/cargo- cargo-credential-wincred = { version = "0.4.7", path = "credential/cargo-credential-wincred" } cargo-platform = { path = "crates/cargo-platform", version = "0.2.0" } cargo-test-macro = { version = "0.4.0", path = "crates/cargo-test-macro" } -cargo-test-support = { version = "0.7.0", path = "crates/cargo-test-support" } +cargo-test-support = { version = "0.7.1", path = "crates/cargo-test-support" } cargo-util = { version = "0.2.14", path = "crates/cargo-util" } cargo-util-schemas = { version = "0.7.0", path = "crates/cargo-util-schemas" } cargo_metadata = "0.19.0" diff --git a/crates/cargo-test-support/Cargo.toml b/crates/cargo-test-support/Cargo.toml index 8c23a2180a1..efd918d2b11 100644 --- a/crates/cargo-test-support/Cargo.toml +++ b/crates/cargo-test-support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-test-support" -version = "0.7.0" +version = "0.7.1" edition.workspace = true rust-version = "1.83" # MSRV:1 license.workspace = true diff --git a/crates/cargo-test-support/src/cross_compile.rs b/crates/cargo-test-support/src/cross_compile.rs index 10af51097f1..d9e61cb2f7e 100644 --- a/crates/cargo-test-support/src/cross_compile.rs +++ b/crates/cargo-test-support/src/cross_compile.rs @@ -267,3 +267,33 @@ pub fn can_run_on_host() -> bool { return true; } } + +/// Check if the given target has been installed. +/// +/// Generally [`disabled`] should be used to check if cross-compilation is allowed. +/// And [`alternate`] to get the cross target. +/// +/// You should only use this as a last resort to skip tests, +/// because it doesn't report skipped tests as ignored. +pub fn requires_target_installed(target: &str) -> bool { + let has_target = std::process::Command::new("rustup") + .args(["target", "list", "--installed"]) + .output() + .ok() + .map(|output| { + String::from_utf8(output.stdout) + .map(|stdout| stdout.contains(target)) + .unwrap_or_default() + }) + .unwrap_or_default(); + if !has_target { + let msg = + format!("to run this test, run `rustup target add {target} --toolchain `",); + if cargo_util::is_ci() { + panic!("{msg}"); + } else { + eprintln!("{msg}"); + } + } + has_target +} diff --git a/tests/testsuite/standard_lib.rs b/tests/testsuite/standard_lib.rs index 9fadc4fb02f..d072a196454 100644 --- a/tests/testsuite/standard_lib.rs +++ b/tests/testsuite/standard_lib.rs @@ -6,6 +6,7 @@ use std::path::{Path, PathBuf}; +use cargo_test_support::cross_compile; use cargo_test_support::prelude::*; use cargo_test_support::registry::{Dependency, Package}; use cargo_test_support::ProjectBuilder; @@ -391,24 +392,8 @@ fn check_core() { #[cargo_test(build_std_mock)] fn build_std_with_no_arg_for_core_only_target() { - let has_rustup_aarch64_unknown_none = std::process::Command::new("rustup") - .args(["target", "list", "--installed"]) - .output() - .ok() - .map(|output| { - String::from_utf8(output.stdout) - .map(|stdout| stdout.contains("aarch64-unknown-none")) - .unwrap_or_default() - }) - .unwrap_or_default(); - if !has_rustup_aarch64_unknown_none { - let msg = - "to run this test, run `rustup target add aarch64-unknown-none --toolchain nightly`"; - if cargo_util::is_ci() { - panic!("{msg}"); - } else { - eprintln!("{msg}"); - } + let target = "aarch64-unknown-none"; + if !cross_compile::requires_target_installed(target) { return; } @@ -427,7 +412,8 @@ fn build_std_with_no_arg_for_core_only_target() { .build(); p.cargo("build -v") - .arg("--target=aarch64-unknown-none") + .arg("--target") + .arg(target) .build_std(&setup) .with_stderr_data( str![[r#" @@ -457,7 +443,8 @@ fn build_std_with_no_arg_for_core_only_target() { // Note that we don't download std dependencies for the second call // because `-Zbuild-std` downloads them all also when building for core only. p.cargo("build -v") - .arg("--target=aarch64-unknown-none") + .arg("--target") + .arg(target) .target_host() .build_std(&setup) .with_stderr_data( From e57a2f43c2858a7ed7df7f01cdb70db7f25486d1 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 8 Jan 2025 15:36:23 -0500 Subject: [PATCH 2/3] test: show that `-Awarnings` fails target info probing This will be resolved in the next commit --- .github/workflows/main.yml | 2 ++ tests/testsuite/cross_compile.rs | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5caebcee6da..04da8bd1688 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -161,6 +161,7 @@ jobs: - run: rustup update --no-self-update stable - run: rustup update --no-self-update ${{ matrix.rust }} && rustup default ${{ matrix.rust }} - run: rustup target add ${{ matrix.other }} + - run: rustup target add wasm32-unknown-unknown - run: rustup target add aarch64-unknown-none # need this for build-std mock tests if: startsWith(matrix.rust, 'nightly') - run: rustup component add rustc-dev llvm-tools-preview rust-docs @@ -225,6 +226,7 @@ jobs: - uses: actions/checkout@v4 - run: rustup update --no-self-update stable && rustup default stable - run: rustup target add i686-unknown-linux-gnu + - run: rustup target add wasm32-unknown-unknown - run: sudo apt update -y && sudo apt install gcc-multilib libsecret-1-0 libsecret-1-dev -y - run: rustup component add rustfmt || echo "rustfmt not available" - run: cargo test -p cargo diff --git a/tests/testsuite/cross_compile.rs b/tests/testsuite/cross_compile.rs index 185c480abb5..92a79bab897 100644 --- a/tests/testsuite/cross_compile.rs +++ b/tests/testsuite/cross_compile.rs @@ -1260,3 +1260,38 @@ fn doctest_xcompile_linker() { "#]]) .run(); } + +#[cargo_test] +fn always_emit_warnings_as_warnings_when_learning_target_info() { + if cross_compile::disabled() { + return; + } + + let target = "wasm32-unknown-unknown"; + if !cross_compile::requires_target_installed(target) { + return; + } + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2015" + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("build -v --target") + .env("RUSTFLAGS", "-Awarnings") + .arg(target) + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] output of --print=file-names missing when learning about target-specific information from rustc +command was: `rustc - --crate-name ___ --print=file-names -Awarnings --target wasm32-unknown-unknown --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=split-debuginfo --print=crate-name --print=cfg` +... +"#]]) + .run(); +} From 5e3558cf071cb941438634e2ee95fe4330256d1e Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 8 Jan 2025 15:10:19 -0500 Subject: [PATCH 3/3] fix: emit warnings as warnings when learning rust target info This is a horrible hack, It lets the rustc invocation for learning target info always emit warnings as warnings. But at least it unblocks people who pass `-Awarnings` via RUSTFLAGS. A long-term solution is a better interface between build systems and the compiler. See the discussion on Zulip: https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Improving.20communication.20interface.20between.20cargo.2Frustc Fixes rust-lang/cargo#8010 --- src/cargo/core/compiler/build_context/target_info.rs | 4 ++++ tests/testsuite/cross_compile.rs | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index 1844073ae45..6a0bea3f79e 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -206,6 +206,10 @@ impl TargetInfo { process.arg("--print=crate-name"); // `___` as a delimiter. process.arg("--print=cfg"); + // parse_crate_type() relies on "unsupported/unknown crate type" error message, + // so make warnings always emitted as warnings. + process.arg("-Wwarnings"); + let (output, error) = rustc .cached_output(&process, extra_fingerprint) .with_context(|| { diff --git a/tests/testsuite/cross_compile.rs b/tests/testsuite/cross_compile.rs index 92a79bab897..54901c35dca 100644 --- a/tests/testsuite/cross_compile.rs +++ b/tests/testsuite/cross_compile.rs @@ -1287,11 +1287,11 @@ fn always_emit_warnings_as_warnings_when_learning_target_info() { p.cargo("build -v --target") .env("RUSTFLAGS", "-Awarnings") .arg(target) - .with_status(101) .with_stderr_data(str![[r#" -[ERROR] output of --print=file-names missing when learning about target-specific information from rustc -command was: `rustc - --crate-name ___ --print=file-names -Awarnings --target wasm32-unknown-unknown --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=split-debuginfo --print=crate-name --print=cfg` -... +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]-Awarnings[..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + "#]]) .run(); }