From 8106668aaf61716c5b2df7b864aa28f07e944bd0 Mon Sep 17 00:00:00 2001 From: El Mehdi YOUNES Date: Tue, 31 Mar 2026 14:24:26 +0200 Subject: [PATCH 1/3] Allow overriding OUT_DIR for test and bench units Some Rust tests embed OUT_DIR-derived paths at compile time, for example through env!("OUT_DIR") or code generated from it. That works while tests run from Cargo's original build tree, but it can break when test binaries are packaged and executed later from a different installed location. In that situation, the original build-time OUT_DIR may no longer exist or may point to paths that should not be embedded in the installed test binary. Cargo already constructs the compile-time environment for test and bench units in artifact.rs::get_env(). Add an opt-in override for OUT_DIR so downstream packaged test environments can redirect it to a valid runtime location when needed. The override is only used for test and bench targets, and only when __CARGO_TEST_OUT_DIR_OVERRIDE is present in Cargo's environment. Cargo's default behavior remains unchanged otherwise. Signed-off-by: El Mehdi YOUNES --- src/cargo/core/compiler/artifact.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cargo/core/compiler/artifact.rs b/src/cargo/core/compiler/artifact.rs index d6b9fc105b3..751a2295959 100644 --- a/src/cargo/core/compiler/artifact.rs +++ b/src/cargo/core/compiler/artifact.rs @@ -17,6 +17,12 @@ pub fn get_env( ) -> CargoResult> { let mut env = HashMap::new(); + if unit.target.is_test() || unit.target.is_bench() { + if let Ok(value) = build_runner.bcx.gctx.get_env("__CARGO_TEST_OUT_DIR_OVERRIDE") { + env.insert("OUT_DIR".to_string(), OsString::from(value)); + } + } + // Add `CARGO_BIN_EXE_` environment variables for building tests. // // These aren't built for `cargo check`, so can't use `dependencies` From b6922da70e2a97f09a4b59f76a18d8992e4795c9 Mon Sep 17 00:00:00 2001 From: El Mehdi YOUNES Date: Tue, 31 Mar 2026 14:35:17 +0200 Subject: [PATCH 2/3] Allow overriding CARGO_MANIFEST_DIR for test and bench units Some Rust tests capture CARGO_MANIFEST_DIR at compile time in order to locate fixtures, test inputs, or other resources relative to the package root. That works while tests execute from Cargo's original workspace layout, but it can break when test binaries are packaged and later executed from a different installed location. In those environments, the original build-time manifest directory may no longer exist or may no longer be the right base directory for installed test data. Cargo already constructs the compile-time environment for test and bench units in artifact.rs::get_env(). Add an opt-in override for CARGO_MANIFEST_DIR so downstream packaged test environments can redirect it to an installed test root when needed. The override is only used for test and bench targets, and only when __CARGO_TEST_MANIFEST_DIR_OVERRIDE is present in Cargo's environment. Cargo's default behavior remains unchanged otherwise. Signed-off-by: El Mehdi YOUNES --- src/cargo/core/compiler/artifact.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cargo/core/compiler/artifact.rs b/src/cargo/core/compiler/artifact.rs index 751a2295959..7a6aa23b39b 100644 --- a/src/cargo/core/compiler/artifact.rs +++ b/src/cargo/core/compiler/artifact.rs @@ -21,6 +21,9 @@ pub fn get_env( if let Ok(value) = build_runner.bcx.gctx.get_env("__CARGO_TEST_OUT_DIR_OVERRIDE") { env.insert("OUT_DIR".to_string(), OsString::from(value)); } + if let Ok(value) = build_runner.bcx.gctx.get_env("__CARGO_TEST_MANIFEST_DIR_OVERRIDE") { + env.insert("CARGO_MANIFEST_DIR".to_string(), OsString::from(value)); + } } // Add `CARGO_BIN_EXE_` environment variables for building tests. From 3357c989c7f0347b23fd0cbf10de831225474a7c Mon Sep 17 00:00:00 2001 From: El Mehdi YOUNES Date: Tue, 31 Mar 2026 15:02:10 +0200 Subject: [PATCH 3/3] Allow overriding CARGO_BIN_EXE paths for test and bench units Some Rust integration tests launch the program under test through compile-time variables such as env!("CARGO_BIN_EXE_"). Cargo already synthesizes CARGO_BIN_EXE_* for test and bench units in artifact.rs::get_env(), normally pointing at a binary location derived from the build tree. That works while tests execute within Cargo's build layout, but it can break when test binaries are packaged and later run from a different installed environment, where the correct program path may instead be something like an installed bindir location. Add an opt-in override that lets downstream packaged test environments redirect the directory used to construct CARGO_BIN_EXE_* values. When __CARGO_TEST_BIN_EXE_DIR_OVERRIDE is set, Cargo builds CARGO_BIN_EXE_ from that directory and the binary filename. Otherwise, Cargo keeps its existing behavior unchanged, including the placeholder fallback for cargo check. Signed-off-by: El Mehdi YOUNES --- src/cargo/core/compiler/artifact.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cargo/core/compiler/artifact.rs b/src/cargo/core/compiler/artifact.rs index 7a6aa23b39b..9554a61a591 100644 --- a/src/cargo/core/compiler/artifact.rs +++ b/src/cargo/core/compiler/artifact.rs @@ -44,12 +44,17 @@ pub fn get_env( // For `cargo check` builds we do not uplift the CARGO_BIN_EXE_ artifacts to the // artifact-dir. We do not want to provide a path to a non-existent binary but we still // need to provide *something* so `env!("CARGO_BIN_EXE_...")` macros will compile. - let exe_path = build_runner + let exe_path = if let Ok(dir) = build_runner.bcx.gctx.get_env("__CARGO_TEST_BIN_EXE_DIR_OVERRIDE") { + let mut path = std::path::PathBuf::from(dir); + path.push(&name); + path.into_os_string() + } else { + build_runner .files() .bin_link_for_target(bin_target, unit.kind, build_runner.bcx)? .map(|path| path.as_os_str().to_os_string()) - .unwrap_or_else(|| OsString::from(format!("placeholder:{name}"))); - + .unwrap_or_else(|| OsString::from(format!("placeholder:{name}"))) + }; let key = format!("CARGO_BIN_EXE_{name}"); env.insert(key, exe_path); }