Skip to content

Commit 223e84a

Browse files
committed
Auto merge of #10844 - yerke:yerke/negative_jobs, r=ehuss
Support for negative --jobs parameter, counting backwards from max CPUs Fixes #9217. Continuation of #9221.
2 parents 2e35678 + 767368f commit 223e84a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+159
-86
lines changed

src/cargo/core/compiler/build_config.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,27 +56,26 @@ impl BuildConfig {
5656
/// * `target.$target.libfoo.metadata`
5757
pub fn new(
5858
config: &Config,
59-
jobs: Option<u32>,
59+
jobs: Option<i32>,
6060
keep_going: bool,
6161
requested_targets: &[String],
6262
mode: CompileMode,
6363
) -> CargoResult<BuildConfig> {
6464
let cfg = config.build_config()?;
6565
let requested_kinds = CompileKind::from_requested_targets(config, requested_targets)?;
66-
if jobs == Some(0) {
67-
anyhow::bail!("jobs must be at least 1")
68-
}
6966
if jobs.is_some() && config.jobserver_from_env().is_some() {
7067
config.shell().warn(
7168
"a `-j` argument was passed to Cargo but Cargo is \
7269
also configured with an external jobserver in \
7370
its environment, ignoring the `-j` parameter",
7471
)?;
7572
}
76-
let jobs = jobs.or(cfg.jobs).unwrap_or(::num_cpus::get() as u32);
77-
if jobs == 0 {
78-
anyhow::bail!("jobs may not be 0");
79-
}
73+
let jobs = match jobs.or(cfg.jobs) {
74+
None => ::num_cpus::get() as u32,
75+
Some(0) => anyhow::bail!("jobs may not be 0"),
76+
Some(j) if j < 0 => (::num_cpus::get() as i32 + j).max(1) as u32,
77+
Some(j) => j as u32,
78+
};
8079

8180
if config.cli_unstable().build_std.is_some() && requested_kinds[0].is_host() {
8281
// TODO: This should eventually be fixed.

src/cargo/core/compiler/context/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
9292
let jobserver = match bcx.config.jobserver_from_env() {
9393
Some(c) => c.clone(),
9494
None => {
95-
let client = Client::new(bcx.build_config.jobs as usize)
95+
let client = Client::new(bcx.jobs() as usize)
9696
.with_context(|| "failed to create jobserver")?;
9797
client.acquire_raw()?;
9898
client
@@ -603,7 +603,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
603603
}
604604

605605
pub fn new_jobserver(&mut self) -> CargoResult<Client> {
606-
let tokens = self.bcx.build_config.jobs as usize;
606+
let tokens = self.bcx.jobs() as usize;
607607
let client = Client::new(tokens).with_context(|| "failed to create jobserver")?;
608608

609609
// Drain the client fully

src/cargo/core/compiler/timings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ impl<'cfg> Timings<'cfg> {
441441
self.total_dirty,
442442
self.total_fresh + self.total_dirty,
443443
max_concurrency,
444-
bcx.build_config.jobs,
444+
bcx.jobs(),
445445
num_cpus::get(),
446446
self.start_str,
447447
total_time,

src/cargo/ops/cargo_package.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub struct PackageOpts<'cfg> {
3030
pub check_metadata: bool,
3131
pub allow_dirty: bool,
3232
pub verify: bool,
33-
pub jobs: Option<u32>,
33+
pub jobs: Option<i32>,
3434
pub keep_going: bool,
3535
pub to_package: ops::Packages,
3636
pub targets: Vec<String>,

src/cargo/ops/registry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub struct PublishOpts<'cfg> {
8080
pub index: Option<String>,
8181
pub verify: bool,
8282
pub allow_dirty: bool,
83-
pub jobs: Option<u32>,
83+
pub jobs: Option<i32>,
8484
pub keep_going: bool,
8585
pub to_publish: ops::Packages,
8686
pub targets: Vec<String>,

src/cargo/util/command_prelude.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ pub trait AppExt: Sized {
6969
self._arg(
7070
opt("jobs", "Number of parallel jobs, defaults to # of CPUs")
7171
.short('j')
72-
.value_name("N"),
72+
.value_name("N")
73+
.allow_hyphen_values(true),
7374
)
7475
._arg(flag(
7576
"keep-going",
@@ -326,6 +327,19 @@ pub trait ArgMatchesExt {
326327
Ok(arg)
327328
}
328329

330+
fn value_of_i32(&self, name: &str) -> CargoResult<Option<i32>> {
331+
let arg = match self._value_of(name) {
332+
None => None,
333+
Some(arg) => Some(arg.parse::<i32>().map_err(|_| {
334+
clap::Error::raw(
335+
clap::ErrorKind::ValueValidation,
336+
format!("Invalid value: could not parse `{}` as a number", arg),
337+
)
338+
})?),
339+
};
340+
Ok(arg)
341+
}
342+
329343
/// Returns value of the `name` command-line argument as an absolute path
330344
fn value_of_path(&self, name: &str, config: &Config) -> Option<PathBuf> {
331345
self._value_of(name).map(|path| config.cwd().join(path))
@@ -359,8 +373,8 @@ pub trait ArgMatchesExt {
359373
Ok(ws)
360374
}
361375

362-
fn jobs(&self) -> CargoResult<Option<u32>> {
363-
self.value_of_u32("jobs")
376+
fn jobs(&self) -> CargoResult<Option<i32>> {
377+
self.value_of_i32("jobs")
364378
}
365379

366380
fn verbose(&self) -> u32 {

src/cargo/util/config/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2195,7 +2195,7 @@ pub struct CargoBuildConfig {
21952195
pub target_dir: Option<ConfigRelativePath>,
21962196
pub incremental: Option<bool>,
21972197
pub target: Option<BuildTargetConfig>,
2198-
pub jobs: Option<u32>,
2198+
pub jobs: Option<i32>,
21992199
pub rustflags: Option<StringList>,
22002200
pub rustdocflags: Option<StringList>,
22012201
pub rustc_wrapper: Option<ConfigRelativePath>,

src/doc/man/generated_txt/cargo-bench.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,9 @@ OPTIONS
373373
Number of parallel jobs to run. May also be specified with the
374374
build.jobs config value
375375
<https://doc.rust-lang.org/cargo/reference/config.html>. Defaults to
376-
the number of CPUs.
376+
the number of logical CPUs. If negative, it sets the maximum number
377+
of parallel jobs to the number of logical CPUs plus provided value.
378+
Should not be 0.
377379

378380
--keep-going
379381
Build as many crates in the dependency graph as possible, rather

src/doc/man/generated_txt/cargo-build.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,9 @@ OPTIONS
318318
Number of parallel jobs to run. May also be specified with the
319319
build.jobs config value
320320
<https://doc.rust-lang.org/cargo/reference/config.html>. Defaults to
321-
the number of CPUs.
321+
the number of logical CPUs. If negative, it sets the maximum number
322+
of parallel jobs to the number of logical CPUs plus provided value.
323+
Should not be 0.
322324

323325
--keep-going
324326
Build as many crates in the dependency graph as possible, rather

src/doc/man/generated_txt/cargo-check.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,9 @@ OPTIONS
303303
Number of parallel jobs to run. May also be specified with the
304304
build.jobs config value
305305
<https://doc.rust-lang.org/cargo/reference/config.html>. Defaults to
306-
the number of CPUs.
306+
the number of logical CPUs. If negative, it sets the maximum number
307+
of parallel jobs to the number of logical CPUs plus provided value.
308+
Should not be 0.
307309

308310
--keep-going
309311
Build as many crates in the dependency graph as possible, rather

0 commit comments

Comments
 (0)