Skip to content

Commit 7bb7b53

Browse files
committed
Auto merge of #12776 - weihanglo:jobserver, r=ehuss
feat: inherit jobserver from env for all kinds of runner
2 parents 0702139 + 678f3ff commit 7bb7b53

File tree

2 files changed

+156
-19
lines changed

2 files changed

+156
-19
lines changed

src/cargo/core/compiler/compilation.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,13 @@ impl<'cfg> Compilation<'cfg> {
257257
} else {
258258
ProcessBuilder::new(cmd)
259259
};
260-
self.fill_env(builder, pkg, script_meta, kind, false)
260+
let mut builder = self.fill_env(builder, pkg, script_meta, kind, false)?;
261+
262+
if let Some(client) = self.config.jobserver_from_env() {
263+
builder.inherit_jobserver(client);
264+
}
265+
266+
Ok(builder)
261267
}
262268

263269
/// Prepares a new process with an appropriate environment to run against

tests/testsuite/jobserver.rs

Lines changed: 149 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
//! Tests for the jobserver protocol.
22
33
use cargo_util::is_ci;
4+
use std::env;
45
use std::net::TcpListener;
56
use std::process::Command;
67
use std::thread;
78

8-
use cargo_test_support::install::{assert_has_installed_exe, cargo_home};
9-
use cargo_test_support::{cargo_exe, project};
9+
use cargo_test_support::basic_bin_manifest;
10+
use cargo_test_support::cargo_exe;
11+
use cargo_test_support::install::assert_has_installed_exe;
12+
use cargo_test_support::install::cargo_home;
13+
use cargo_test_support::project;
14+
use cargo_test_support::rustc_host;
1015

1116
const EXE_CONTENT: &str = r#"
1217
use std::env;
1318
1419
fn main() {
15-
let var = env::var("CARGO_MAKEFLAGS").unwrap();
20+
let var = env::var("CARGO_MAKEFLAGS").expect("no jobserver from env");
1621
let arg = var.split(' ')
1722
.find(|p| p.starts_with("--jobserver"))
1823
.unwrap();
@@ -49,6 +54,14 @@ fn validate(_: &str) {
4954
}
5055
"#;
5156

57+
fn make_exe() -> &'static str {
58+
if cfg!(windows) {
59+
"mingw32-make"
60+
} else {
61+
"make"
62+
}
63+
}
64+
5265
#[cargo_test]
5366
fn jobserver_exists() {
5467
let p = project()
@@ -64,11 +77,7 @@ fn jobserver_exists() {
6477

6578
#[cargo_test]
6679
fn external_subcommand_inherits_jobserver() {
67-
let make = if cfg!(windows) {
68-
"mingw32-make"
69-
} else {
70-
"make"
71-
};
80+
let make = make_exe();
7281
if Command::new(make).arg("--version").output().is_err() {
7382
return;
7483
}
@@ -101,13 +110,139 @@ all:
101110
p.process(make).env("CARGO", cargo_exe()).arg("-j2").run();
102111
}
103112

113+
#[cargo_test]
114+
fn runner_inherits_jobserver() {
115+
let make = make_exe();
116+
if Command::new(make).arg("--version").output().is_err() {
117+
return;
118+
}
119+
120+
let runner = "runner";
121+
project()
122+
.at(runner)
123+
.file("Cargo.toml", &basic_bin_manifest(runner))
124+
.file(
125+
"src/main.rs",
126+
r#"
127+
pub fn main() {
128+
eprintln!("this is a runner");
129+
let args: Vec<String> = std::env::args().collect();
130+
let status = std::process::Command::new(&args[1]).status().unwrap();
131+
assert!(status.success());
132+
}
133+
"#,
134+
)
135+
.build()
136+
.cargo("install --path .")
137+
.run();
138+
139+
// Add .cargo/bin to PATH
140+
let mut path: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect();
141+
path.push(cargo_home().join("bin"));
142+
let path = &env::join_paths(path).unwrap();
143+
assert_has_installed_exe(cargo_home(), runner);
144+
145+
let host = rustc_host();
146+
let config_value = &format!("target.{host}.runner = \"{runner}\"");
147+
148+
let name = "cargo-jobserver-check";
149+
let p = project()
150+
.file(
151+
"Cargo.toml",
152+
&format!(
153+
r#"
154+
[package]
155+
name = "{name}"
156+
version = "0.0.1"
157+
"#
158+
),
159+
)
160+
.file(
161+
"src/lib.rs",
162+
r#"
163+
#[test]
164+
fn test() {
165+
_ = std::env::var("CARGO_MAKEFLAGS").expect("no jobserver from env");
166+
}
167+
"#,
168+
)
169+
.file("src/main.rs", EXE_CONTENT)
170+
.file(
171+
"Makefile",
172+
&format!(
173+
"\
174+
run:
175+
\t+$(CARGO) run
176+
177+
run-runner:
178+
\t+$(CARGO) run --config '{config_value}'
179+
180+
test:
181+
\t+$(CARGO) test --lib
182+
183+
test-runner:
184+
\t+$(CARGO) test --lib --config '{config_value}'
185+
",
186+
),
187+
)
188+
.build();
189+
190+
// jobserver can be inherited from env
191+
p.process(make)
192+
.env("CARGO", cargo_exe())
193+
.arg("run")
194+
.arg("-j2")
195+
.run();
196+
p.process(make)
197+
.env("PATH", path)
198+
.env("CARGO", cargo_exe())
199+
.arg("run-runner")
200+
.arg("-j2")
201+
.with_stderr_contains("[..]this is a runner[..]")
202+
.run();
203+
p.process(make)
204+
.env("CARGO", cargo_exe())
205+
.arg("test")
206+
.arg("-j2")
207+
.run();
208+
p.process(make)
209+
.env("PATH", path)
210+
.env("CARGO", cargo_exe())
211+
.arg("test-runner")
212+
.arg("-j2")
213+
.with_stderr_contains("[..]this is a runner[..]")
214+
.run();
215+
216+
// but not from `-j` flag
217+
p.cargo("run -j2")
218+
.with_status(101)
219+
.with_stderr_contains("[..]no jobserver from env[..]")
220+
.run();
221+
p.cargo("run -j2")
222+
.env("PATH", path)
223+
.arg("--config")
224+
.arg(config_value)
225+
.with_status(101)
226+
.with_stderr_contains("[..]this is a runner[..]")
227+
.with_stderr_contains("[..]no jobserver from env[..]")
228+
.run();
229+
p.cargo("test -j2")
230+
.with_status(101)
231+
.with_stdout_contains("[..]no jobserver from env[..]")
232+
.run();
233+
p.cargo("test -j2")
234+
.env("PATH", path)
235+
.arg("--config")
236+
.arg(config_value)
237+
.with_status(101)
238+
.with_stderr_contains("[..]this is a runner[..]")
239+
.with_stdout_contains("[..]no jobserver from env[..]")
240+
.run();
241+
}
242+
104243
#[cargo_test]
105244
fn makes_jobserver_used() {
106-
let make = if cfg!(windows) {
107-
"mingw32-make"
108-
} else {
109-
"make"
110-
};
245+
let make = make_exe();
111246
if !is_ci() && Command::new(make).arg("--version").output().is_err() {
112247
return;
113248
}
@@ -215,11 +350,7 @@ all:
215350

216351
#[cargo_test]
217352
fn jobserver_and_j() {
218-
let make = if cfg!(windows) {
219-
"mingw32-make"
220-
} else {
221-
"make"
222-
};
353+
let make = make_exe();
223354
if !is_ci() && Command::new(make).arg("--version").output().is_err() {
224355
return;
225356
}

0 commit comments

Comments
 (0)