Set an environment variable for tests to find executables.

This commit is contained in:
Eric Huss 2019-12-11 08:26:08 -08:00
parent db0dac507e
commit 3489428921
4 changed files with 104 additions and 1 deletions

View File

@ -10,7 +10,7 @@ use log::info;
use super::{BuildContext, CompileKind, Context, FileFlavor, Layout};
use crate::core::compiler::{CompileMode, CompileTarget, Unit};
use crate::core::{TargetKind, Workspace};
use crate::core::{Target, TargetKind, Workspace};
use crate::util::{self, CargoResult};
/// The `Metadata` is a hash used to make unique file names for each unit in a build.
@ -241,6 +241,36 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
}
}
/// Returns the path to the executable binary for the given bin target.
///
/// This should only to be used when a `Unit` is not available.
pub fn bin_link_for_target(
&self,
target: &Target,
kind: CompileKind,
bcx: &BuildContext<'_, '_>,
) -> CargoResult<PathBuf> {
assert!(target.is_bin());
let dest = self.layout(kind).dest();
let info = bcx.info(kind);
let file_types = info
.file_types(
"bin",
FileFlavor::Normal,
&TargetKind::Bin,
kind.short_name(bcx),
)?
.expect("target must support `bin`");
let file_type = file_types
.iter()
.filter(|file_type| file_type.flavor == FileFlavor::Normal)
.next()
.expect("target must support `bin`");
Ok(dest.join(file_type.filename(target.name())))
}
/// Returns the filenames that the given unit will generate.
pub(super) fn outputs(
&self,

View File

@ -876,6 +876,23 @@ fn build_base_args<'a, 'cfg>(
cmd.arg("-Zforce-unstable-if-unmarked")
.env("RUSTC_BOOTSTRAP", "1");
}
// Add `CARGO_BIN_` environment variables for building tests.
if unit.target.is_test() || unit.target.is_bench() {
for bin_target in unit
.pkg
.manifest()
.targets()
.iter()
.filter(|target| target.is_bin())
{
let exe_path = cx
.files()
.bin_link_for_target(bin_target, unit.kind, cx.bcx)?;
let key = format!("CARGO_BIN_EXE_{}", bin_target.crate_name().to_uppercase());
cmd.env(&key, exe_path);
}
}
Ok(())
}

View File

@ -187,6 +187,15 @@ let version = env!("CARGO_PKG_VERSION");
* `OUT_DIR` — If the package has a build script, this is set to the folder where the build
script should place its output. See below for more information.
(Only set during compilation.)
* `CARGO_BIN_EXE_<name>` The absolute path to a binary target's executable.
This is only set when building an [integration test] or benchmark. This may
be used with the [`env` macro] to find the executable to run for testing
purposes. The `<name>` is the name of the binary converted to uppercase, and
`-` converted to `_`. Binaries are automatically built when the test is
built, unless the binary has required features that are not enabled.
[integration test]: manifest.md#integration-tests
[`env` macro]: ../../std/macro.env.html
#### Dynamic library paths

View File

@ -3995,3 +3995,50 @@ fn panic_abort_test_profile_inherits() {
.with_status(0)
.run();
}
#[cargo_test]
fn bin_env_for_test() {
// Test for the `CARGO_BIN_` environment variables for tests.
//
// Note: The Unicode binary uses a `[[bin]]` definition because different
// filesystems normalize utf-8 in different ways. For example, HFS uses
// "gru\u{308}ßen" and APFS uses "gr\u{fc}ßen". Defining it in TOML forces
// one form to be used.
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[[bin]]
name = 'grüßen'
path = 'src/bin/grussen.rs'
"#,
)
.file("src/bin/foo.rs", "fn main() {}")
.file("src/bin/with-dash.rs", "fn main() {}")
.file("src/bin/grussen.rs", "fn main() {}")
.build();
let bin_path = |name| p.bin(name).to_string_lossy().replace("\\", "\\\\");
p.change_file(
"tests/check_env.rs",
&r#"
#[test]
fn run_bins() {
assert_eq!(env!("CARGO_BIN_EXE_FOO"), "<FOO_PATH>");
assert_eq!(env!("CARGO_BIN_EXE_WITH_DASH"), "<WITH_DASH_PATH>");
assert_eq!(env!("CARGO_BIN_EXE_GRÜSSEN"), "<GRÜSSEN_PATH>");
}
"#
.replace("<FOO_PATH>", &bin_path("foo"))
.replace("<WITH_DASH_PATH>", &bin_path("with-dash"))
.replace("<GRÜSSEN_PATH>", &bin_path("grüßen")),
);
p.cargo("test --test check_env").run();
p.cargo("check --test check_env").run();
}