Skip to content

Commit

Permalink
Auto merge of #12776 - weihanglo:jobserver, r=ehuss
Browse files Browse the repository at this point in the history
feat: inherit jobserver from env for all kinds of runner
  • Loading branch information
bors committed Jan 20, 2024
2 parents 0702139 + 678f3ff commit 7bb7b53
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 19 deletions.
8 changes: 7 additions & 1 deletion src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,13 @@ impl<'cfg> Compilation<'cfg> {
} else {
ProcessBuilder::new(cmd)
};
self.fill_env(builder, pkg, script_meta, kind, false)
let mut builder = self.fill_env(builder, pkg, script_meta, kind, false)?;

if let Some(client) = self.config.jobserver_from_env() {
builder.inherit_jobserver(client);
}

Ok(builder)
}

/// Prepares a new process with an appropriate environment to run against
Expand Down
167 changes: 149 additions & 18 deletions tests/testsuite/jobserver.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
//! Tests for the jobserver protocol.

use cargo_util::is_ci;
use std::env;
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};
use cargo_test_support::basic_bin_manifest;
use cargo_test_support::cargo_exe;
use cargo_test_support::install::assert_has_installed_exe;
use cargo_test_support::install::cargo_home;
use cargo_test_support::project;
use cargo_test_support::rustc_host;

const EXE_CONTENT: &str = r#"
use std::env;
fn main() {
let var = env::var("CARGO_MAKEFLAGS").unwrap();
let var = env::var("CARGO_MAKEFLAGS").expect("no jobserver from env");
let arg = var.split(' ')
.find(|p| p.starts_with("--jobserver"))
.unwrap();
Expand Down Expand Up @@ -49,6 +54,14 @@ fn validate(_: &str) {
}
"#;

fn make_exe() -> &'static str {
if cfg!(windows) {
"mingw32-make"
} else {
"make"
}
}

#[cargo_test]
fn jobserver_exists() {
let p = project()
Expand All @@ -64,11 +77,7 @@ fn jobserver_exists() {

#[cargo_test]
fn external_subcommand_inherits_jobserver() {
let make = if cfg!(windows) {
"mingw32-make"
} else {
"make"
};
let make = make_exe();
if Command::new(make).arg("--version").output().is_err() {
return;
}
Expand Down Expand Up @@ -101,13 +110,139 @@ all:
p.process(make).env("CARGO", cargo_exe()).arg("-j2").run();
}

#[cargo_test]
fn runner_inherits_jobserver() {
let make = make_exe();
if Command::new(make).arg("--version").output().is_err() {
return;
}

let runner = "runner";
project()
.at(runner)
.file("Cargo.toml", &basic_bin_manifest(runner))
.file(
"src/main.rs",
r#"
pub fn main() {
eprintln!("this is a runner");
let args: Vec<String> = std::env::args().collect();
let status = std::process::Command::new(&args[1]).status().unwrap();
assert!(status.success());
}
"#,
)
.build()
.cargo("install --path .")
.run();

// Add .cargo/bin to PATH
let mut path: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect();
path.push(cargo_home().join("bin"));
let path = &env::join_paths(path).unwrap();
assert_has_installed_exe(cargo_home(), runner);

let host = rustc_host();
let config_value = &format!("target.{host}.runner = \"{runner}\"");

let name = "cargo-jobserver-check";
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "{name}"
version = "0.0.1"
"#
),
)
.file(
"src/lib.rs",
r#"
#[test]
fn test() {
_ = std::env::var("CARGO_MAKEFLAGS").expect("no jobserver from env");
}
"#,
)
.file("src/main.rs", EXE_CONTENT)
.file(
"Makefile",
&format!(
"\
run:
\t+$(CARGO) run
run-runner:
\t+$(CARGO) run --config '{config_value}'
test:
\t+$(CARGO) test --lib
test-runner:
\t+$(CARGO) test --lib --config '{config_value}'
",
),
)
.build();

// jobserver can be inherited from env
p.process(make)
.env("CARGO", cargo_exe())
.arg("run")
.arg("-j2")
.run();
p.process(make)
.env("PATH", path)
.env("CARGO", cargo_exe())
.arg("run-runner")
.arg("-j2")
.with_stderr_contains("[..]this is a runner[..]")
.run();
p.process(make)
.env("CARGO", cargo_exe())
.arg("test")
.arg("-j2")
.run();
p.process(make)
.env("PATH", path)
.env("CARGO", cargo_exe())
.arg("test-runner")
.arg("-j2")
.with_stderr_contains("[..]this is a runner[..]")
.run();

// but not from `-j` flag
p.cargo("run -j2")
.with_status(101)
.with_stderr_contains("[..]no jobserver from env[..]")
.run();
p.cargo("run -j2")
.env("PATH", path)
.arg("--config")
.arg(config_value)
.with_status(101)
.with_stderr_contains("[..]this is a runner[..]")
.with_stderr_contains("[..]no jobserver from env[..]")
.run();
p.cargo("test -j2")
.with_status(101)
.with_stdout_contains("[..]no jobserver from env[..]")
.run();
p.cargo("test -j2")
.env("PATH", path)
.arg("--config")
.arg(config_value)
.with_status(101)
.with_stderr_contains("[..]this is a runner[..]")
.with_stdout_contains("[..]no jobserver from env[..]")
.run();
}

#[cargo_test]
fn makes_jobserver_used() {
let make = if cfg!(windows) {
"mingw32-make"
} else {
"make"
};
let make = make_exe();
if !is_ci() && Command::new(make).arg("--version").output().is_err() {
return;
}
Expand Down Expand Up @@ -215,11 +350,7 @@ all:

#[cargo_test]
fn jobserver_and_j() {
let make = if cfg!(windows) {
"mingw32-make"
} else {
"make"
};
let make = make_exe();
if !is_ci() && Command::new(make).arg("--version").output().is_err() {
return;
}
Expand Down

0 comments on commit 7bb7b53

Please sign in to comment.