Skip to content

Commit 140144b

Browse files
committed
Auto merge of #6688 - ehuss:incremental-cleanup, r=alexcrichton
Incremental profile cleanup. Some minor code cleanup, and doc updates regarding incremental compilation. Move incremental logic into the profile computation, which makes it a little more consistent and helps simplify things a little (such as removing the fingerprint special-case). This introduces a small change in behavior with the `build.incremental` config variable. Previously `build.incremental = true` was completely ignored. Now, it is treated the same as `CARGO_INCREMENTAL=1` environment variable. Moves config profile validation to the workspace so that warnings do not appear multiple times (once for each manifest). Split from #6643.
2 parents dc83ead + 2b6fd6f commit 140144b

File tree

12 files changed

+89
-104
lines changed

12 files changed

+89
-104
lines changed

Diff for: src/cargo/core/compiler/build_context/mod.rs

-7
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ pub struct BuildContext<'a, 'cfg: 'a> {
3838
pub target_config: TargetConfig,
3939
pub target_info: TargetInfo,
4040
pub host_info: TargetInfo,
41-
pub incremental_env: Option<bool>,
4241
}
4342

4443
impl<'a, 'cfg> BuildContext<'a, 'cfg> {
@@ -51,11 +50,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
5150
profiles: &'a Profiles,
5251
extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
5352
) -> CargoResult<BuildContext<'a, 'cfg>> {
54-
let incremental_env = match env::var("CARGO_INCREMENTAL") {
55-
Ok(v) => Some(v == "1"),
56-
Err(_) => None,
57-
};
58-
5953
let rustc = config.rustc(Some(ws))?;
6054
let host_config = TargetConfig::new(config, &rustc.host)?;
6155
let target_config = match build_config.requested_target.as_ref() {
@@ -84,7 +78,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
8478
host_info,
8579
build_config,
8680
profiles,
87-
incremental_env,
8881
extra_compiler_args,
8982
})
9083
}

Diff for: src/cargo/core/compiler/context/mod.rs

-55
Original file line numberDiff line numberDiff line change
@@ -386,61 +386,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
386386
deps
387387
}
388388

389-
pub fn incremental_args(&self, unit: &Unit<'_>) -> CargoResult<Vec<String>> {
390-
// There's a number of ways to configure incremental compilation right
391-
// now. In order of descending priority (first is highest priority) we
392-
// have:
393-
//
394-
// * `CARGO_INCREMENTAL` - this is blanket used unconditionally to turn
395-
// on/off incremental compilation for any cargo subcommand. We'll
396-
// respect this if set.
397-
// * `build.incremental` - in `.cargo/config` this blanket key can
398-
// globally for a system configure whether incremental compilation is
399-
// enabled. Note that setting this to `true` will not actually affect
400-
// all builds though. For example a `true` value doesn't enable
401-
// release incremental builds, only dev incremental builds. This can
402-
// be useful to globally disable incremental compilation like
403-
// `CARGO_INCREMENTAL`.
404-
// * `profile.dev.incremental` - in `Cargo.toml` specific profiles can
405-
// be configured to enable/disable incremental compilation. This can
406-
// be primarily used to disable incremental when buggy for a package.
407-
// * Finally, each profile has a default for whether it will enable
408-
// incremental compilation or not. Primarily development profiles
409-
// have it enabled by default while release profiles have it disabled
410-
// by default.
411-
let global_cfg = self
412-
.bcx
413-
.config
414-
.get_bool("build.incremental")?
415-
.map(|c| c.val);
416-
let incremental = match (
417-
self.bcx.incremental_env,
418-
global_cfg,
419-
unit.profile.incremental,
420-
) {
421-
(Some(v), _, _) => v,
422-
(None, Some(false), _) => false,
423-
(None, _, other) => other,
424-
};
425-
426-
if !incremental {
427-
return Ok(Vec::new());
428-
}
429-
430-
// Only enable incremental compilation for sources the user can
431-
// modify (aka path sources). For things that change infrequently,
432-
// non-incremental builds yield better performance in the compiler
433-
// itself (aka crates.io / git dependencies)
434-
//
435-
// (see also https://github.com/rust-lang/cargo/issues/3972)
436-
if !unit.pkg.package_id().source_id().is_path() {
437-
return Ok(Vec::new());
438-
}
439-
440-
let dir = self.files().layout(unit.kind).incremental().display();
441-
Ok(vec!["-C".to_string(), format!("incremental={}", dir)])
442-
}
443-
444389
pub fn is_primary_package(&self, unit: &Unit<'a>) -> bool {
445390
self.primary_packages.contains(&unit.pkg.package_id())
446391
}

Diff for: src/cargo/core/compiler/fingerprint.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -492,12 +492,7 @@ fn calculate<'a, 'cfg>(
492492
} else {
493493
bcx.rustflags_args(unit)?
494494
};
495-
let profile_hash = util::hash_u64(&(
496-
&unit.profile,
497-
unit.mode,
498-
bcx.extra_args_for(unit),
499-
cx.incremental_args(unit)?,
500-
));
495+
let profile_hash = util::hash_u64(&(&unit.profile, unit.mode, bcx.extra_args_for(unit)));
501496
let fingerprint = Arc::new(Fingerprint {
502497
rustc: util::hash_u64(&bcx.rustc.verbose_version),
503498
target: util::hash_u64(&unit.target),

Diff for: src/cargo/core/compiler/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ fn build_base_args<'a, 'cfg>(
760760
overflow_checks,
761761
rpath,
762762
ref panic,
763+
incremental,
763764
..
764765
} = unit.profile;
765766
let test = unit.mode.is_any_test();
@@ -902,8 +903,10 @@ fn build_base_args<'a, 'cfg>(
902903
"linker=",
903904
bcx.linker(unit.kind).map(|s| s.as_ref()),
904905
);
905-
cmd.args(&cx.incremental_args(unit)?);
906-
906+
if incremental {
907+
let dir = cx.files().layout(unit.kind).incremental().as_os_str();
908+
opt(cmd, "-C", "incremental=", Some(dir));
909+
}
907910
Ok(())
908911
}
909912

Diff for: src/cargo/core/manifest.rs

+7
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub struct VirtualManifest {
6666
workspace: WorkspaceConfig,
6767
profiles: Profiles,
6868
warnings: Warnings,
69+
features: Features,
6970
}
7071

7172
/// General metadata about a package which is just blindly uploaded to the
@@ -541,13 +542,15 @@ impl VirtualManifest {
541542
patch: HashMap<Url, Vec<Dependency>>,
542543
workspace: WorkspaceConfig,
543544
profiles: Profiles,
545+
features: Features,
544546
) -> VirtualManifest {
545547
VirtualManifest {
546548
replace,
547549
patch,
548550
workspace,
549551
profiles,
550552
warnings: Warnings::new(),
553+
features,
551554
}
552555
}
553556

@@ -574,6 +577,10 @@ impl VirtualManifest {
574577
pub fn warnings(&self) -> &Warnings {
575578
&self.warnings
576579
}
580+
581+
pub fn features(&self) -> &Features {
582+
&self.features
583+
}
577584
}
578585

579586
impl Target {

Diff for: src/cargo/core/profiles.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::collections::HashSet;
2-
use std::{cmp, fmt, hash};
2+
use std::{cmp, env, fmt, hash};
33

44
use serde::Deserialize;
55

@@ -19,6 +19,10 @@ pub struct Profiles {
1919
test: ProfileMaker,
2020
bench: ProfileMaker,
2121
doc: ProfileMaker,
22+
/// Incremental compilation can be overridden globally via:
23+
/// - `CARGO_INCREMENTAL` environment variable.
24+
/// - `build.incremental` config value.
25+
incremental: Option<bool>,
2226
}
2327

2428
impl Profiles {
@@ -33,7 +37,11 @@ impl Profiles {
3337
}
3438

3539
let config_profiles = config.profiles()?;
36-
config_profiles.validate(features, warnings)?;
40+
41+
let incremental = match env::var_os("CARGO_INCREMENTAL") {
42+
Some(v) => Some(v == "1"),
43+
None => config.get::<Option<bool>>("build.incremental")?,
44+
};
3745

3846
Ok(Profiles {
3947
dev: ProfileMaker {
@@ -61,6 +69,7 @@ impl Profiles {
6169
toml: profiles.and_then(|p| p.doc.clone()),
6270
config: None,
6371
},
72+
incremental,
6473
})
6574
}
6675

@@ -100,10 +109,25 @@ impl Profiles {
100109
CompileMode::Doc { .. } => &self.doc,
101110
};
102111
let mut profile = maker.get_profile(Some(pkg_id), is_member, unit_for);
103-
// `panic` should not be set for tests/benches, or any of their dependencies.
112+
// `panic` should not be set for tests/benches, or any of their
113+
// dependencies.
104114
if !unit_for.is_panic_ok() || mode.is_any_test() {
105115
profile.panic = None;
106116
}
117+
118+
// Incremental can be globally overridden.
119+
if let Some(v) = self.incremental {
120+
profile.incremental = v;
121+
}
122+
// Only enable incremental compilation for sources the user can
123+
// modify (aka path sources). For things that change infrequently,
124+
// non-incremental builds yield better performance in the compiler
125+
// itself (aka crates.io / git dependencies)
126+
//
127+
// (see also https://github.com/rust-lang/cargo/issues/3972)
128+
if !pkg_id.source_id().is_path() {
129+
profile.incremental = false;
130+
}
107131
profile
108132
}
109133

Diff for: src/cargo/core/workspace.rs

+30-21
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,9 @@ impl<'cfg> Workspace<'cfg> {
237237
}
238238

239239
pub fn profiles(&self) -> &Profiles {
240-
let root = self
241-
.root_manifest
242-
.as_ref()
243-
.unwrap_or(&self.current_manifest);
244-
match *self.packages.get(root) {
245-
MaybePackage::Package(ref p) => p.manifest().profiles(),
246-
MaybePackage::Virtual(ref vm) => vm.profiles(),
240+
match self.root_maybe() {
241+
MaybePackage::Package(p) => p.manifest().profiles(),
242+
MaybePackage::Virtual(vm) => vm.profiles(),
247243
}
248244
}
249245

@@ -260,6 +256,15 @@ impl<'cfg> Workspace<'cfg> {
260256
.unwrap()
261257
}
262258

259+
/// Returns the root Package or VirtualManifest.
260+
fn root_maybe(&self) -> &MaybePackage {
261+
let root = self
262+
.root_manifest
263+
.as_ref()
264+
.unwrap_or(&self.current_manifest);
265+
self.packages.get(root)
266+
}
267+
263268
pub fn target_dir(&self) -> Filesystem {
264269
self.target_dir
265270
.clone()
@@ -270,27 +275,19 @@ impl<'cfg> Workspace<'cfg> {
270275
///
271276
/// This may be from a virtual crate or an actual crate.
272277
pub fn root_replace(&self) -> &[(PackageIdSpec, Dependency)] {
273-
let path = match self.root_manifest {
274-
Some(ref p) => p,
275-
None => &self.current_manifest,
276-
};
277-
match *self.packages.get(path) {
278-
MaybePackage::Package(ref p) => p.manifest().replace(),
279-
MaybePackage::Virtual(ref vm) => vm.replace(),
278+
match self.root_maybe() {
279+
MaybePackage::Package(p) => p.manifest().replace(),
280+
MaybePackage::Virtual(vm) => vm.replace(),
280281
}
281282
}
282283

283284
/// Returns the root [patch] section of this workspace.
284285
///
285286
/// This may be from a virtual crate or an actual crate.
286287
pub fn root_patch(&self) -> &HashMap<Url, Vec<Dependency>> {
287-
let path = match self.root_manifest {
288-
Some(ref p) => p,
289-
None => &self.current_manifest,
290-
};
291-
match *self.packages.get(path) {
292-
MaybePackage::Package(ref p) => p.manifest().patch(),
293-
MaybePackage::Virtual(ref vm) => vm.patch(),
288+
match self.root_maybe() {
289+
MaybePackage::Package(p) => p.manifest().patch(),
290+
MaybePackage::Virtual(vm) => vm.patch(),
294291
}
295292
}
296293

@@ -524,6 +521,18 @@ impl<'cfg> Workspace<'cfg> {
524521
/// 2. All workspace members agree on this one root as the root.
525522
/// 3. The current crate is a member of this workspace.
526523
fn validate(&mut self) -> CargoResult<()> {
524+
// Validate config profiles only once per workspace.
525+
let features = match self.root_maybe() {
526+
MaybePackage::Package(p) => p.manifest().features(),
527+
MaybePackage::Virtual(vm) => vm.features(),
528+
};
529+
let mut warnings = Vec::new();
530+
self.config.profiles()?.validate(features, &mut warnings)?;
531+
for warning in warnings {
532+
self.config.shell().warn(&warning)?;
533+
}
534+
535+
// The rest of the checks require a VirtualManifest or multiple members.
527536
if self.root_manifest.is_none() {
528537
return Ok(());
529538
}

Diff for: src/cargo/util/toml/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ impl TomlManifest {
11371137
}
11381138
};
11391139
Ok((
1140-
VirtualManifest::new(replace, patch, workspace_config, profiles),
1140+
VirtualManifest::new(replace, patch, workspace_config, profiles, features),
11411141
nested_paths,
11421142
))
11431143
}

Diff for: src/doc/src/reference/config.md

+2
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ target-dir = "target" # path of where to place all generated artifacts
129129
rustflags = ["..", ".."] # custom flags to pass to all compiler invocations
130130
rustdocflags = ["..", ".."] # custom flags to pass to rustdoc
131131
incremental = true # whether or not to enable incremental compilation
132+
# If `incremental` is not set, then the value from
133+
# the profile is used.
132134
dep-info-basedir = ".." # full path for the base directory for targets in depfiles
133135

134136
[term]

Diff for: src/doc/src/reference/manifest.md

+3
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ codegen-units = 16 # if > 1 enables parallel code generation which improves
374374
# Passes `-C codegen-units`.
375375
panic = 'unwind' # panic strategy (`-C panic=...`), can also be 'abort'
376376
incremental = true # whether or not incremental compilation is enabled
377+
# This can be overridden globally with the CARGO_INCREMENTAL
378+
# environment variable or `build.incremental` config
379+
# variable. Incremental is only used for path sources.
377380
overflow-checks = true # use overflow checks for integer arithmetic.
378381
# Passes the `-C overflow-checks=...` flag to the compiler.
379382

Diff for: tests/testsuite/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn cargo_fail_with_no_stderr() {
3737
}
3838

3939
/// Checks that the `CARGO_INCREMENTAL` environment variable results in
40-
/// `rustc` getting `-Zincremental` passed to it.
40+
/// `rustc` getting `-C incremental` passed to it.
4141
#[test]
4242
fn cargo_compile_incremental() {
4343
let p = project()

0 commit comments

Comments
 (0)