From: Ingvar Stepanyan Date: Wed, 26 Apr 2017 00:16:17 +0000 (+0100) Subject: Add support for custom target-specific runners X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~22^2~9^2~39^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=e1a85a607c5599d4116ecd6394a33674875581b9;p=cargo.git Add support for custom target-specific runners When `target.$triple.runner` is specified, it will be used for any execution commands by cargo including `cargo run`, `cargo test` and `cargo bench`. The original file is passed to the runner executable as a first argument. This allows to run tests when cross-comping Rust projects. This is not a complete solution, and might be extended in future for better ergonomics to support passing extra arguments to the runner itself or overriding runner from command line, but it should already unlock major existing usecases. Fixes #1411 Resolves #3626 --- diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 1256787f4..26faf702e 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -662,8 +662,11 @@ fn scrape_target_config(config: &Config, triple: &str) None => return Ok(ret), }; for (lib_name, value) in table { - if lib_name == "ar" || lib_name == "linker" || lib_name == "rustflags" { - continue + match lib_name.as_str() { + "ar" | "linker" | "runner" | "rustflags" => { + continue + }, + _ => {} } let mut output = BuildOutput { diff --git a/src/cargo/ops/cargo_rustc/compilation.rs b/src/cargo/ops/cargo_rustc/compilation.rs index b34850a79..594f3cb19 100644 --- a/src/cargo/ops/cargo_rustc/compilation.rs +++ b/src/cargo/ops/cargo_rustc/compilation.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use semver::Version; use core::{PackageId, Package, Target, TargetKind}; -use util::{self, CargoResult, Config, ProcessBuilder, process, join_paths}; +use util::{self, CargoResult, Config, LazyCell, ProcessBuilder, process, join_paths}; /// A structure returning the result of a compilation. pub struct Compilation<'cfg> { @@ -53,6 +53,8 @@ pub struct Compilation<'cfg> { pub target: String, config: &'cfg Config, + + target_runner: LazyCell>, } impl<'cfg> Compilation<'cfg> { @@ -72,6 +74,7 @@ impl<'cfg> Compilation<'cfg> { cfgs: HashMap::new(), config: config, target: String::new(), + target_runner: LazyCell::new(), } } @@ -91,10 +94,24 @@ impl<'cfg> Compilation<'cfg> { self.fill_env(process(cmd), pkg, true) } + fn target_runner(&self) -> CargoResult<&Option> { + self.target_runner.get_or_try_init(|| { + let key = format!("target.{}.runner", self.target); + Ok(self.config.get_path(&key)?.map(|v| v.val)) + }) + } + /// See `process`. pub fn target_process>(&self, cmd: T, pkg: &Package) -> CargoResult { - self.fill_env(process(cmd), pkg, false) + let builder = if let &Some(ref runner) = self.target_runner()? { + let mut builder = process(runner); + builder.arg(cmd); + builder + } else { + process(cmd) + }; + self.fill_env(builder, pkg, false) } /// Prepares a new process with an appropriate environment to run against diff --git a/tests/tool-paths.rs b/tests/tool-paths.rs index dcb9e6368..641ccba9a 100644 --- a/tests/tool-paths.rs +++ b/tests/tool-paths.rs @@ -124,3 +124,48 @@ fn relative_tools() { [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", url = foo_url, ar = output.0, linker = output.1))) } + +#[test] +fn custom_runner() { + let target = rustc_host(); + + let foo = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + "#) + .file("src/main.rs", "fn main() {}") + .file("tests/test.rs", "") + .file("benches/bench.rs", "") + .file(".cargo/config", &format!(r#" + [target.{}] + runner = "nonexistent-runner" + "#, target)); + + foo.build(); + + assert_that(foo.cargo("run").args(&["--", "--param"]), + execs().with_stderr_contains(&format!("\ +[COMPILING] foo v0.0.1 ({url}) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[RUNNING] `nonexistent-runner target[/]debug[/]foo[EXE] --param` +", url = foo.url()))); + + assert_that(foo.cargo("test").args(&["--test", "test", "--verbose", "--", "--param"]), + execs().with_stderr_contains(&format!("\ +[COMPILING] foo v0.0.1 ({url}) +[RUNNING] `rustc [..]` +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[RUNNING] `nonexistent-runner [..][/]target[/]debug[/]deps[/]test-[..][EXE] --param` +", url = foo.url()))); + + assert_that(foo.cargo("bench").args(&["--bench", "bench", "--verbose", "--", "--param"]), + execs().with_stderr_contains(&format!("\ +[COMPILING] foo v0.0.1 ({url}) +[RUNNING] `rustc [..]` +[RUNNING] `rustc [..]` +[FINISHED] release [optimized] target(s) in [..] +[RUNNING] `nonexistent-runner [..][/]target[/]release[/]deps[/]bench-[..][EXE] --param --bench` +", url = foo.url()))); +}