diff --git a/src/cargo/core/compiler/build_config.rs b/src/cargo/core/compiler/build_config.rs
index 9e97eb485f4..51c9bf77871 100644
--- a/src/cargo/core/compiler/build_config.rs
+++ b/src/cargo/core/compiler/build_config.rs
@@ -56,16 +56,13 @@ impl BuildConfig {
/// * `target.$target.libfoo.metadata`
pub fn new(
config: &Config,
- jobs: Option,
+ jobs: Option,
keep_going: bool,
requested_targets: &[String],
mode: CompileMode,
) -> CargoResult {
let cfg = config.build_config()?;
let requested_kinds = CompileKind::from_requested_targets(config, requested_targets)?;
- if jobs == Some(0) {
- anyhow::bail!("jobs must be at least 1")
- }
if jobs.is_some() && config.jobserver_from_env().is_some() {
config.shell().warn(
"a `-j` argument was passed to Cargo but Cargo is \
@@ -73,10 +70,12 @@ impl BuildConfig {
its environment, ignoring the `-j` parameter",
)?;
}
- let jobs = jobs.or(cfg.jobs).unwrap_or(::num_cpus::get() as u32);
- if jobs == 0 {
- anyhow::bail!("jobs may not be 0");
- }
+ let jobs = match jobs.or(cfg.jobs) {
+ None => ::num_cpus::get() as u32,
+ Some(0) => anyhow::bail!("jobs may not be 0"),
+ Some(j) if j < 0 => (::num_cpus::get() as i32 + j).max(1) as u32,
+ Some(j) => j as u32,
+ };
if config.cli_unstable().build_std.is_some() && requested_kinds[0].is_host() {
// TODO: This should eventually be fixed.
diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs
index 40ab6aaf38e..75da79024b1 100644
--- a/src/cargo/core/compiler/context/mod.rs
+++ b/src/cargo/core/compiler/context/mod.rs
@@ -92,7 +92,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
let jobserver = match bcx.config.jobserver_from_env() {
Some(c) => c.clone(),
None => {
- let client = Client::new(bcx.build_config.jobs as usize)
+ let client = Client::new(bcx.jobs() as usize)
.with_context(|| "failed to create jobserver")?;
client.acquire_raw()?;
client
@@ -603,7 +603,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
}
pub fn new_jobserver(&mut self) -> CargoResult {
- let tokens = self.bcx.build_config.jobs as usize;
+ let tokens = self.bcx.jobs() as usize;
let client = Client::new(tokens).with_context(|| "failed to create jobserver")?;
// Drain the client fully
diff --git a/src/cargo/core/compiler/timings.rs b/src/cargo/core/compiler/timings.rs
index bd846053f25..7c5b13a0e5a 100644
--- a/src/cargo/core/compiler/timings.rs
+++ b/src/cargo/core/compiler/timings.rs
@@ -441,7 +441,7 @@ impl<'cfg> Timings<'cfg> {
self.total_dirty,
self.total_fresh + self.total_dirty,
max_concurrency,
- bcx.build_config.jobs,
+ bcx.jobs(),
num_cpus::get(),
self.start_str,
total_time,
diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs
index a86e73d1f3d..270e1d70d3a 100644
--- a/src/cargo/ops/cargo_package.rs
+++ b/src/cargo/ops/cargo_package.rs
@@ -30,7 +30,7 @@ pub struct PackageOpts<'cfg> {
pub check_metadata: bool,
pub allow_dirty: bool,
pub verify: bool,
- pub jobs: Option,
+ pub jobs: Option,
pub keep_going: bool,
pub to_package: ops::Packages,
pub targets: Vec,
diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs
index 303b9466d7e..b343a813f79 100644
--- a/src/cargo/ops/registry.rs
+++ b/src/cargo/ops/registry.rs
@@ -80,7 +80,7 @@ pub struct PublishOpts<'cfg> {
pub index: Option,
pub verify: bool,
pub allow_dirty: bool,
- pub jobs: Option,
+ pub jobs: Option,
pub keep_going: bool,
pub to_publish: ops::Packages,
pub targets: Vec,
diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs
index 95491c86766..5d197b9f117 100644
--- a/src/cargo/util/command_prelude.rs
+++ b/src/cargo/util/command_prelude.rs
@@ -69,7 +69,8 @@ pub trait AppExt: Sized {
self._arg(
opt("jobs", "Number of parallel jobs, defaults to # of CPUs")
.short('j')
- .value_name("N"),
+ .value_name("N")
+ .allow_hyphen_values(true),
)
._arg(flag(
"keep-going",
@@ -326,6 +327,19 @@ pub trait ArgMatchesExt {
Ok(arg)
}
+ fn value_of_i32(&self, name: &str) -> CargoResult
--jobsN
Number of parallel jobs to run. May also be specified with the
build.jobsconfig value. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
Number of parallel jobs to run. May also be specified with the
build.jobsconfig value. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
Number of parallel jobs to run. May also be specified with the
build.jobsconfig value. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
--keep-going
diff --git a/src/doc/src/commands/cargo-run.md b/src/doc/src/commands/cargo-run.md
index e0fa5ccac3e..5b5f79f2fbe 100644
--- a/src/doc/src/commands/cargo-run.md
+++ b/src/doc/src/commands/cargo-run.md
@@ -281,7 +281,9 @@ for more information about how toolchain overrides work.
--jobsN
Number of parallel jobs to run. May also be specified with the
build.jobsconfig value. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
--keep-going
diff --git a/src/doc/src/commands/cargo-rustc.md b/src/doc/src/commands/cargo-rustc.md
index d7a18baebb6..fea0de2b57f 100644
--- a/src/doc/src/commands/cargo-rustc.md
+++ b/src/doc/src/commands/cargo-rustc.md
@@ -382,7 +382,9 @@ for more information about how toolchain overrides work.
--jobsN
Number of parallel jobs to run. May also be specified with the
build.jobsconfig value. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
--keep-going
diff --git a/src/doc/src/commands/cargo-rustdoc.md b/src/doc/src/commands/cargo-rustdoc.md
index 8f795050519..3e1a4b8615b 100644
--- a/src/doc/src/commands/cargo-rustdoc.md
+++ b/src/doc/src/commands/cargo-rustdoc.md
@@ -362,7 +362,9 @@ for more information about how toolchain overrides work.
--jobsN
Number of parallel jobs to run. May also be specified with the
build.jobsconfig value. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
--keep-going
diff --git a/src/doc/src/commands/cargo-test.md b/src/doc/src/commands/cargo-test.md
index 8e7a812e995..783523bb40f 100644
--- a/src/doc/src/commands/cargo-test.md
+++ b/src/doc/src/commands/cargo-test.md
@@ -474,7 +474,9 @@ includes an option to control the number of threads used:
--jobsN
Number of parallel jobs to run. May also be specified with the
build.jobsconfig value. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
--keep-going
diff --git a/src/doc/src/reference/config.md b/src/doc/src/reference/config.md
index 365ca5daab9..ee330b6e198 100644
--- a/src/doc/src/reference/config.md
+++ b/src/doc/src/reference/config.md
@@ -344,7 +344,9 @@ The `[build]` table controls build-time operations and compiler settings.
* Default: number of logical CPUs
* Environment: `CARGO_BUILD_JOBS`
-Sets the maximum number of compiler processes to run in parallel.
+Sets the maximum number of compiler processes to run in parallel. If negative,
+it sets the maximum number of compiler processes to the number of logical CPUs
+plus provided value. Should not be 0.
Can be overridden with the `--jobs` CLI option.
diff --git a/src/etc/man/cargo-bench.1 b/src/etc/man/cargo-bench.1
index 21e07fbbcd6..f14027cd067 100644
--- a/src/etc/man/cargo-bench.1
+++ b/src/etc/man/cargo-bench.1
@@ -469,7 +469,9 @@ Rust test harness runs benchmarks serially in a single thread.
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-build.1 b/src/etc/man/cargo-build.1
index 8ddfd548254..d8e548e518d 100644
--- a/src/etc/man/cargo-build.1
+++ b/src/etc/man/cargo-build.1
@@ -396,7 +396,9 @@ Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fR for details.
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-check.1 b/src/etc/man/cargo-check.1
index 4e39a23e40d..7c096a57529 100644
--- a/src/etc/man/cargo-check.1
+++ b/src/etc/man/cargo-check.1
@@ -377,7 +377,9 @@ Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fR for details.
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-doc.1 b/src/etc/man/cargo-doc.1
index aa06c1033da..0d7a74d3348 100644
--- a/src/etc/man/cargo-doc.1
+++ b/src/etc/man/cargo-doc.1
@@ -344,7 +344,9 @@ Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fR for details.
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-fix.1 b/src/etc/man/cargo-fix.1
index 95a75d6a59a..4ee3628d549 100644
--- a/src/etc/man/cargo-fix.1
+++ b/src/etc/man/cargo-fix.1
@@ -472,7 +472,9 @@ Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fR for details.
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-install.1 b/src/etc/man/cargo-install.1
index 72fc87ff136..7f2db3f5fe9 100644
--- a/src/etc/man/cargo-install.1
+++ b/src/etc/man/cargo-install.1
@@ -325,7 +325,9 @@ May also be specified with the \fBnet.offline\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-package.1 b/src/etc/man/cargo-package.1
index 6504d243d1a..bcb3b02ae93 100644
--- a/src/etc/man/cargo-package.1
+++ b/src/etc/man/cargo-package.1
@@ -233,7 +233,9 @@ May also be specified with the \fBnet.offline\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-publish.1 b/src/etc/man/cargo-publish.1
index 6417023d3f6..5d0ebc0b960 100644
--- a/src/etc/man/cargo-publish.1
+++ b/src/etc/man/cargo-publish.1
@@ -183,7 +183,9 @@ May also be specified with the \fBnet.offline\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-run.1 b/src/etc/man/cargo-run.1
index 241e0b2e161..c1902aa822f 100644
--- a/src/etc/man/cargo-run.1
+++ b/src/etc/man/cargo-run.1
@@ -277,7 +277,9 @@ Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fR for details.
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-rustc.1 b/src/etc/man/cargo-rustc.1
index 02dba7b26ec..9fa0173dcb8 100644
--- a/src/etc/man/cargo-rustc.1
+++ b/src/etc/man/cargo-rustc.1
@@ -395,7 +395,9 @@ Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fR for details.
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-rustdoc.1 b/src/etc/man/cargo-rustdoc.1
index ce8fc408af8..903fcc13296 100644
--- a/src/etc/man/cargo-rustdoc.1
+++ b/src/etc/man/cargo-rustdoc.1
@@ -363,7 +363,9 @@ Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fR for details.
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/src/etc/man/cargo-test.1 b/src/etc/man/cargo-test.1
index 662cb1bdb63..3a8c1bb4582 100644
--- a/src/etc/man/cargo-test.1
+++ b/src/etc/man/cargo-test.1
@@ -494,7 +494,9 @@ cargo test \-j 2 \-\- \-\-test\-threads=2
.RS 4
Number of parallel jobs to run. May also be specified with the
\fBbuild.jobs\fR \fIconfig value\fR \&. Defaults to
-the number of CPUs.
+the number of logical CPUs. If negative, it sets the maximum number of
+parallel jobs to the number of logical CPUs plus provided value.
+Should not be 0.
.RE
.sp
\fB\-\-keep\-going\fR
diff --git a/tests/testsuite/bad_config.rs b/tests/testsuite/bad_config.rs
index 06f9b449b26..4e1d483e4c3 100644
--- a/tests/testsuite/bad_config.rs
+++ b/tests/testsuite/bad_config.rs
@@ -138,32 +138,6 @@ Caused by:
.run();
}
-#[cargo_test]
-fn bad_cargo_config_jobs() {
- let p = project()
- .file("src/lib.rs", "")
- .file(
- ".cargo/config",
- r#"
- [build]
- jobs = -1
- "#,
- )
- .build();
- p.cargo("build -v")
- .with_status(101)
- .with_stderr(
- "\
-[ERROR] error in [..].cargo/config: \
-could not load config key `build.jobs`
-
-Caused by:
- invalid value: integer `-1`, expected u32
-",
- )
- .run();
-}
-
#[cargo_test]
fn invalid_global_config() {
let p = project()
diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs
index b12d33a0214..e738f246d1b 100644
--- a/tests/testsuite/build.rs
+++ b/tests/testsuite/build.rs
@@ -5416,6 +5416,18 @@ fn good_cargo_config_jobs() {
p.cargo("build -v").run();
}
+#[cargo_test]
+fn good_jobs() {
+ let p = project()
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
+ .build();
+
+ p.cargo("build --jobs 1").run();
+
+ p.cargo("build --jobs -1").run();
+}
+
#[cargo_test]
fn invalid_cargo_config_jobs() {
let p = project()
@@ -5441,11 +5453,9 @@ fn invalid_jobs() {
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
- p.cargo("build --jobs -1")
- .with_status(1)
- .with_stderr_contains(
- "error: Found argument '-1' which wasn't expected, or isn't valid in this context",
- )
+ p.cargo("build --jobs 0")
+ .with_status(101)
+ .with_stderr_contains("error: jobs may not be 0")
.run();
p.cargo("build --jobs over9000")