From b96f9f45fc25c351d56de3b011cd90590f556592 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 8 Jul 2026 22:17:14 -0400 Subject: [PATCH 1/3] test: capture runner selection for host artifacts Captured behaviors are likely bugs introduced by rust-lang/cargo#17123 See also rust-lang/miri#5101 --- tests/testsuite/build_script.rs | 92 ++++++++ tests/testsuite/tool_paths.rs | 358 +++++++++++++++++++++++++++++++- 2 files changed, 449 insertions(+), 1 deletion(-) diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 0b99a912ffc..37caba17796 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -1038,6 +1038,98 @@ fn target_runner_does_not_apply_to_build_script() { .run(); } +#[cargo_test] +fn target_runner_build_script_with_target() { + let target = rustc_host(); + let p = project() + .file( + ".cargo/config.toml", + &format!( + r#" + [target.{target}] + runner = "nonexistent-runner" + [target.'cfg(all())'] + runner = "nonexistent-cfg-runner" + "#, + ), + ) + .file("build.rs", "fn main() {}") + .file("src/lib.rs", "") + .build(); + + p.cargo("check -v --target") + .arg(&target) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name build_script_build [..]` +[RUNNING] `[ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build` +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn target_cfg_runner_build_script_with_host_config_and_target() { + let target = rustc_host(); + let p = project() + .file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + runner = "nonexistent-cfg-runner" + "#, + ) + .file("build.rs", "fn main() {}") + .file("src/lib.rs", "") + .build(); + + p.cargo("check -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(&target) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name build_script_build [..]` +[RUNNING] `[ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build` +[RUNNING] `rustc --crate-name foo [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn host_runner_build_script_without_target() { + let p = project() + .file( + ".cargo/config.toml", + r#" + [host] + runner = "nonexistent-host-runner" + "#, + ) + .file("build.rs", "fn main() {}") + .file("src/lib.rs", "") + .build(); + + p.cargo("check -Ztarget-applies-to-host -Zhost-config") + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[ERROR] failed to run custom build command for `foo v0.0.1 ([ROOT]/foo)` + +Caused by: + could not execute process `nonexistent-host-runner [ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build` (never executed) + +Caused by: + [NOT_FOUND] + +"#]]) + .run(); +} + #[cargo_test] fn custom_build_script_wrong_rustc_flags() { let p = project() diff --git a/tests/testsuite/tool_paths.rs b/tests/testsuite/tool_paths.rs index 9da5027d3df..543ae6ea031 100644 --- a/tests/testsuite/tool_paths.rs +++ b/tests/testsuite/tool_paths.rs @@ -1,7 +1,9 @@ //! Tests for configuration values that point to programs. use crate::prelude::*; -use cargo_test_support::{basic_lib_manifest, project, rustc_host, rustc_host_env, str}; +use crate::utils::cross_compile::disabled as cross_compile_disabled; +use cargo_test_support::cross_compile::alternate as cross_compile_alternate; +use cargo_test_support::{Project, basic_lib_manifest, project, rustc_host, rustc_host_env, str}; #[cargo_test] fn pathless_tools() { @@ -442,6 +444,341 @@ Caused by: .run(); } +#[cargo_test] +fn custom_runner_proc_macro_test() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [target.{target}] + runner = "nonexistent-runner -r" + "#, + ), + ); + + p.cargo("test --lib -v") + .with_status(101) + .with_stderr_data(str![[r#" +... +[RUNNING] `nonexistent-runner -r [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` +[ERROR] test failed, to rerun pass `--lib` + +Caused by: + could not execute process `nonexistent-runner -r [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` (never executed) + +Caused by: + [NOT_FOUND] + +"#]]) + .run(); +} + +#[cargo_test] +fn custom_runner_cfg_proc_macro_test() { + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + runner = "nonexistent-runner -r" + "#, + ); + + p.cargo("test --lib -v") + .with_status(101) + .with_stderr_data(str![[r#" +... +[RUNNING] `nonexistent-runner -r [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` +[ERROR] test failed, to rerun pass `--lib` + +Caused by: + could not execute process `nonexistent-runner -r [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` (never executed) + +Caused by: + [NOT_FOUND] + +"#]]) + .run(); +} + +#[cargo_test] +fn custom_runner_proc_macro_test_with_target() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [target.{target}] + runner = "nonexistent-runner -r" + "#, + ), + ); + + p.cargo("test --lib -v --target") + .arg(&target) + .with_status(101) + .with_stderr_data(str![[r#" +... +[RUNNING] `nonexistent-runner -r [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` +[ERROR] test failed, to rerun pass `--lib` + +Caused by: + could not execute process `nonexistent-runner -r [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` (never executed) + +Caused by: + [NOT_FOUND] + +"#]]) + .run(); +} + +#[cargo_test] +fn custom_runner_cfg_proc_macro_test_with_target() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + runner = "nonexistent-runner -r" + "#, + ); + + p.cargo("test --lib -v --target") + .arg(&target) + .with_stderr_data(str![[r#" +... +[RUNNING] `[ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` + +"#]]) + .with_stdout_data(str![[r#" +... +running 1 test +... +"#]]) + .run(); +} + +#[cargo_test] +fn custom_runner_proc_macro_test_with_host_config() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [host] + runner = "nonexistent-host-runner" + [target.{target}] + runner = "nonexistent-target-runner" + "#, + ), + ); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(&target) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_status(101) + .with_stderr_data(str![[r#" +... +[RUNNING] `nonexistent-target-runner [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` +[ERROR] test failed, to rerun pass `--lib` + +Caused by: + could not execute process `nonexistent-target-runner [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` (never executed) + +Caused by: + [NOT_FOUND] + +"#]]) + .run(); +} + +#[cargo_test] +fn custom_runner_cfg_proc_macro_test_with_host_config() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [host] + runner = "nonexistent-host-runner" + [target.'cfg(all())'] + runner = "nonexistent-cfg-runner" + "#, + ); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(&target) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_status(101) + .with_stderr_data(str![[r#" +... +[RUNNING] `nonexistent-cfg-runner [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` +[ERROR] test failed, to rerun pass `--lib` + +Caused by: + could not execute process `nonexistent-cfg-runner [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` (never executed) + +Caused by: + [NOT_FOUND] + +"#]]) + .run(); +} + +#[cargo_test] +fn custom_runner_cfg_proc_macro_test_with_host_config_no_target() { + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [host] + runner = "nonexistent-host-runner" + [target.'cfg(all())'] + runner = "nonexistent-cfg-runner" + "#, + ); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config") + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_status(101) + .with_stderr_data(str![[r#" +... +[RUNNING] `nonexistent-cfg-runner [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` +[ERROR] test failed, to rerun pass `--lib` + +Caused by: + could not execute process `nonexistent-cfg-runner [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` (never executed) + +Caused by: + [NOT_FOUND] + +"#]]) + .run(); +} + +#[cargo_test] +fn host_runner_proc_macro_test() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [host] + runner = "nonexistent-host-runner" + "#, + ); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(&target) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_stderr_data(str![[r#" +... +[RUNNING] `[ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` + +"#]]) + .with_stdout_data(str![[r#" +... +running 1 test +... +"#]]) + .run(); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config") + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_stderr_data(str![[r#" +... +[RUNNING] `[ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` + +"#]]) + .with_stdout_data(str![[r#" +... +running 1 test +... +"#]]) + .run(); +} + +#[cargo_test] +fn custom_runner_proc_macro_test_with_cross_target() { + if cross_compile_disabled() { + return; + } + let target = rustc_host(); + let alternate = cross_compile_alternate(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [target.{target}] + runner = "nonexistent-runner -r" + [target.'cfg(all())'] + runner = "nonexistent-cfg-runner" + "#, + ), + ); + + p.cargo("test --lib -v --target") + .arg(alternate) + .with_status(101) + .with_stderr_data(str![[r#" +... +[RUNNING] `nonexistent-runner -r [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` +[ERROR] test failed, to rerun pass `--lib` + +Caused by: + could not execute process `nonexistent-runner -r [ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` (never executed) + +Caused by: + [NOT_FOUND] + +"#]]) + .run(); +} + +#[cargo_test] +fn custom_runner_proc_macro_test_with_cross_target_host_config() { + if cross_compile_disabled() { + return; + } + let target = rustc_host(); + let alternate = cross_compile_alternate(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [host] + runner = "nonexistent-host-runner" + [target.{target}] + runner = "nonexistent-runner -r" + [target.'cfg(all())'] + runner = "nonexistent-cfg-runner" + "#, + ), + ); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(alternate) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_stderr_data(str![[r#" +... +[RUNNING] `[ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` + +"#]]) + .with_stdout_data(str![[r#" +... +running 1 test +... +"#]]) + .run(); +} + #[cargo_test] fn custom_linker_env() { let p = project().file("src/main.rs", "fn main() {}").build(); @@ -519,3 +856,22 @@ fn cfg_ignored_fields() { "#]]) .run(); } + +/// Creates a bare proc-macro package with a unit test. +fn proc_macro_package() -> Project { + project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.0" + edition = "2015" + + [lib] + proc-macro = true + "#, + ) + .file("src/lib.rs", "#[test] fn it_works() {}") + .build() +} From 0dd05da43b570af14915a241fe9c8f3a800f5aac Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 9 Jul 2026 11:30:44 -0400 Subject: [PATCH 2/3] test: capture linker selection for host artifacts --- tests/testsuite/build_script.rs | 111 +++++++++++++ tests/testsuite/tool_paths.rs | 275 ++++++++++++++++++++++++++++++++ 2 files changed, 386 insertions(+) diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 37caba17796..4457205f2f2 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -1130,6 +1130,117 @@ Caused by: .run(); } +#[cargo_test] +fn target_cfg_linker_build_script() { + let p = project() + .file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + linker = "/path/to/cfg/linker" + "#, + ) + .file("build.rs", "fn main() {}") + .file("src/lib.rs", "") + .build(); + + p.cargo("build -v") + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name build_script_build [..]--crate-type bin [..]-C linker=[..]/path/to/cfg/linker [..]` +[ERROR] linker `[..]/path/to/cfg/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_cfg_linker_build_script_with_target() { + let target = rustc_host(); + let p = project() + .file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + linker = "/path/to/cfg/linker" + "#, + ) + .file("build.rs", "fn main() {}") + .file("src/lib.rs", "") + .build(); + + p.cargo("build -v --target") + .arg(&target) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name build_script_build [..]--crate-type bin [..]` +[RUNNING] `[ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build` +[RUNNING] `rustc --crate-name foo [..]-C linker=[..]/path/to/cfg/linker [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn target_linker_build_script_with_target() { + let target = rustc_host(); + let p = project() + .file( + ".cargo/config.toml", + &format!( + r#" + [target.{target}] + linker = "/path/to/target/linker" + "#, + ), + ) + .file("build.rs", "fn main() {}") + .file("src/lib.rs", "") + .build(); + + p.cargo("build -v --target") + .arg(&target) + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name build_script_build [..]--crate-type bin [..]-C linker=[..]/path/to/target/linker [..]` +[ERROR] linker `[..]/path/to/target/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_cfg_linker_build_script_with_host_config_and_target() { + let target = rustc_host(); + let p = project() + .file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + linker = "/path/to/cfg/linker" + "#, + ) + .file("build.rs", "fn main() {}") + .file("src/lib.rs", "") + .build(); + + p.cargo("build -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(&target) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name build_script_build [..]--crate-type bin [..]` +[RUNNING] `[ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build` +[RUNNING] `rustc --crate-name foo [..]-C linker=[..]/path/to/cfg/linker [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + #[cargo_test] fn custom_build_script_wrong_rustc_flags() { let p = project() diff --git a/tests/testsuite/tool_paths.rs b/tests/testsuite/tool_paths.rs index 543ae6ea031..9e877f466e7 100644 --- a/tests/testsuite/tool_paths.rs +++ b/tests/testsuite/tool_paths.rs @@ -779,6 +779,281 @@ running 1 test .run(); } +#[cargo_test] +fn target_cfg_linker_proc_macro_with_target() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + linker = "/path/to/cfg/linker" + "#, + ); + + p.cargo("build -v --target") + .arg(&target) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--crate-type proc-macro [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn host_linker_proc_macro() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [host] + linker = "/path/to/host/linker" + [target.{target}] + linker = "/path/to/target/linker" + "#, + ), + ); + + p.cargo("build -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(&target) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--crate-type proc-macro [..]-C linker=[..]/path/to/host/linker [..]` +[ERROR] linker `[..]/path/to/host/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_linker_proc_macro_test() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [target.{target}] + linker = "/path/to/target/linker" + "#, + ), + ); + + p.cargo("test --lib -v") + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--test [..]-C linker=[..]/path/to/target/linker [..]` +[ERROR] linker `[..]/path/to/target/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_cfg_linker_proc_macro_test() { + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + linker = "/path/to/cfg/linker" + "#, + ); + + p.cargo("test --lib -v") + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--test [..]-C linker=[..]/path/to/cfg/linker [..]` +[ERROR] linker `[..]/path/to/cfg/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_linker_proc_macro_test_with_target() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [target.{target}] + linker = "/path/to/target/linker" + "#, + ), + ); + + p.cargo("test --lib -v --target") + .arg(&target) + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--test [..]-C linker=[..]/path/to/target/linker [..]` +[ERROR] linker `[..]/path/to/target/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_cfg_linker_proc_macro_test_with_target() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [target.'cfg(all())'] + linker = "/path/to/cfg/linker" + "#, + ); + + p.cargo("test --lib -v --target") + .arg(&target) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--test [..]` +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `[ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` + +"#]]) + .with_stdout_data(str![[r#" +... +running 1 test +... +"#]]) + .run(); +} + +#[cargo_test] +fn host_linker_proc_macro_test() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [host] + linker = "/path/to/host/linker" + [target.{target}] + linker = "/path/to/target/linker" + "#, + ), + ); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(&target) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--test [..]-C linker=[..]/path/to/host/linker [..]` +[ERROR] linker `[..]/path/to/host/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_cfg_linker_proc_macro_test_with_host_config() { + let target = rustc_host(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + r#" + [host] + linker = "/path/to/host/linker" + [target.'cfg(all())'] + linker = "/path/to/cfg/linker" + "#, + ); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(&target) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--test [..]-C linker=[..]/path/to/host/linker [..]` +[ERROR] linker `[..]/path/to/host/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_linker_proc_macro_test_with_cross_target() { + if cross_compile_disabled() { + return; + } + let target = rustc_host(); + let alternate = cross_compile_alternate(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [target.{target}] + linker = "/path/to/target/linker" + "#, + ), + ); + + p.cargo("test --lib -v --target") + .arg(alternate) + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--test [..]-C linker=[..]/path/to/target/linker [..]` +[ERROR] linker `[..]/path/to/target/linker` not found +... +"#]]) + .run(); +} + +#[cargo_test] +fn target_linker_proc_macro_test_with_cross_target_host_config() { + if cross_compile_disabled() { + return; + } + let target = rustc_host(); + let alternate = cross_compile_alternate(); + let p = proc_macro_package(); + p.change_file( + ".cargo/config.toml", + &format!( + r#" + [host] + linker = "/path/to/host/linker" + [target.{target}] + linker = "/path/to/target/linker" + [target.'cfg(all())'] + linker = "/path/to/cfg/linker" + "#, + ), + ); + + p.cargo("test --lib -v -Ztarget-applies-to-host -Zhost-config --target") + .arg(alternate) + .masquerade_as_nightly_cargo(&["target-applies-to-host", "host-config"]) + .with_status(101) + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..]--test [..]-C linker=[..]/path/to/host/linker [..]` +[ERROR] linker `[..]/path/to/host/linker` not found +... +"#]]) + .run(); +} + #[cargo_test] fn custom_linker_env() { let p = project().file("src/main.rs", "fn main() {}").build(); From e9ca1323a6ea7728ad8be9fa432166e0acbfaf07 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 10 Jul 2026 09:22:17 -0400 Subject: [PATCH 3/3] fix: dont apply host-config gating to stable behavior rust-lang/cargo#17123 made host artifacts stop picking up `target.'cfg(..)'.runner` and `target.'cfg(..)'.linker` even without `-Ztarget-applies-to-host -Zhost-config`. That silently changed stable behavior that `target.'cfg(..)'` no longer applied to proc-macro and build script compilation under `--target `, while `target.` config still did. The old gate reused `host_artifact_uses_only_host_config`, which is for the documented rustflags dual behavior. It wasn't for runner and linker. This PR narrows the gate to `target-applies-to-host = false` and restore to pre PR 17123 stable behavior, while keeping `-Zhost-config` fix as it is still nightly. --- src/cargo/core/compiler/build_context/mod.rs | 1 - .../compiler/build_context/target_info.rs | 2 +- src/cargo/core/compiler/compilation.rs | 13 +++++--- tests/testsuite/build_script.rs | 9 +++-- tests/testsuite/tool_paths.rs | 33 +++++++++---------- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/cargo/core/compiler/build_context/mod.rs b/src/cargo/core/compiler/build_context/mod.rs index 18935af38b9..0a08bf621e7 100644 --- a/src/cargo/core/compiler/build_context/mod.rs +++ b/src/cargo/core/compiler/build_context/mod.rs @@ -21,7 +21,6 @@ pub use self::target_info::FileFlavor; pub use self::target_info::FileType; pub use self::target_info::RustcTargetData; pub use self::target_info::TargetInfo; -pub(crate) use self::target_info::host_artifact_uses_only_host_config; /// The build context, containing complete information needed for a build task /// before it gets started. diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index 5067aea2a0d..368155c6924 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -909,7 +909,7 @@ fn rustflags_from_build(gctx: &GlobalContext, flag: Flags) -> CargoResult