diff --git a/src/bin/cargo/main.rs b/src/bin/cargo/main.rs index e4f224031cd..0ec0cc1f6ad 100644 --- a/src/bin/cargo/main.rs +++ b/src/bin/cargo/main.rs @@ -181,11 +181,12 @@ fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> Cli }; let cargo_exe = config.cargo_exe()?; - let err = match ProcessBuilder::new(&command) - .env(cargo::CARGO_ENV, cargo_exe) - .args(args) - .exec_replace() - { + let mut cmd = ProcessBuilder::new(&command); + cmd.env(cargo::CARGO_ENV, cargo_exe).args(args); + if let Some(client) = config.jobserver_from_env() { + cmd.inherit_jobserver(client); + } + let err = match cmd.exec_replace() { Ok(()) => return Ok(()), Err(e) => e, }; diff --git a/tests/testsuite/jobserver.rs b/tests/testsuite/jobserver.rs index da6c1cfa885..bcac3fbb35d 100644 --- a/tests/testsuite/jobserver.rs +++ b/tests/testsuite/jobserver.rs @@ -5,50 +5,50 @@ use std::net::TcpListener; use std::process::Command; use std::thread; +use cargo_test_support::install::{assert_has_installed_exe, cargo_home}; use cargo_test_support::{cargo_exe, project}; -#[cargo_test] -fn jobserver_exists() { - let p = project() - .file( - "build.rs", - r#" - use std::env; +const EXE_CONTENT: &str = r#" +use std::env; - fn main() { - let var = env::var("CARGO_MAKEFLAGS").unwrap(); - let arg = var.split(' ') - .find(|p| p.starts_with("--jobserver")) - .unwrap(); - let val = &arg[arg.find('=').unwrap() + 1..]; - validate(val); - } +fn main() { + let var = env::var("CARGO_MAKEFLAGS").unwrap(); + let arg = var.split(' ') + .find(|p| p.starts_with("--jobserver")) + .unwrap(); + let val = &arg[arg.find('=').unwrap() + 1..]; + validate(val); +} - #[cfg(unix)] - fn validate(s: &str) { - use std::fs::File; - use std::io::*; - use std::os::unix::prelude::*; - - let fds = s.split(',').collect::>(); - println!("{}", s); - assert_eq!(fds.len(), 2); - unsafe { - let mut read = File::from_raw_fd(fds[0].parse().unwrap()); - let mut write = File::from_raw_fd(fds[1].parse().unwrap()); - - let mut buf = [0]; - assert_eq!(read.read(&mut buf).unwrap(), 1); - assert_eq!(write.write(&buf).unwrap(), 1); - } - } +#[cfg(unix)] +fn validate(s: &str) { + use std::fs::File; + use std::io::*; + use std::os::unix::prelude::*; + + let fds = s.split(',').collect::>(); + println!("{}", s); + assert_eq!(fds.len(), 2); + unsafe { + let mut read = File::from_raw_fd(fds[0].parse().unwrap()); + let mut write = File::from_raw_fd(fds[1].parse().unwrap()); + + let mut buf = [0]; + assert_eq!(read.read(&mut buf).unwrap(), 1); + assert_eq!(write.write(&buf).unwrap(), 1); + } +} - #[cfg(windows)] - fn validate(_: &str) { - // a little too complicated for a test... - } - "#, - ) +#[cfg(windows)] +fn validate(_: &str) { + // a little too complicated for a test... +} +"#; + +#[cargo_test] +fn jobserver_exists() { + let p = project() + .file("build.rs", EXE_CONTENT) .file("src/lib.rs", "") .build(); @@ -58,6 +58,45 @@ fn jobserver_exists() { p.cargo("build -j2").run(); } +#[cargo_test] +fn external_subcommand_inherits_jobserver() { + let make = if cfg!(windows) { + "mingw32-make" + } else { + "make" + }; + if Command::new(make).arg("--version").output().is_err() { + return; + } + + let name = "cargo-jobserver-check"; + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "{name}" + version = "0.0.1" + "# + ), + ) + .file("src/main.rs", EXE_CONTENT) + .file( + "Makefile", + "\ +all: +\t+$(CARGO) jobserver-check +", + ) + .build(); + + p.cargo("install --path .").run(); + assert_has_installed_exe(cargo_home(), name); + + p.process(make).env("CARGO", cargo_exe()).arg("-j2").run(); +} + #[cargo_test] fn makes_jobserver_used() { let make = if cfg!(windows) {