Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable incremental by default #4817

Merged
merged 1 commit into from
Dec 21, 2017

Conversation

alexcrichton
Copy link
Member

This commit enables incremental compilation by default in Cargo for all
dev-related profiles (aka anything without --release or bench. A
number of new configuration options were also added to tweak how
incremental compilation is exposed and/or used:

  • A profile.dev.incremental field is added to Cargo.toml to disable
    it on a per-project basis (in case of bugs).
  • A build.incremental field was added in .cargo/config to disable
    globally (or enable if we flip this default back off).

Otherwise CARGO_INCREMENTAL can still be used to configure one
particular compilation. The global build.incremental configuration
cannot currently be used to enable it for the release profile.

@rust-highfive
Copy link

r? @matklad

(rust_highfive has picked a reviewer for you, use r? to override)

@alexcrichton
Copy link
Member Author

Note that this is intended to land roughly the same time we rename -Z to -C for the incremental option but I haven't done that quite just yet to ensure that this still passes CI. We'll probably want to hold off on landing until that's ready to go on the rust-lang/rust side of things.

cc @michaelwoerister @nikomatsakis

Copy link
Member

@matklad matklad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add tests for profile and .cargo/config configuration?

A question I'd like to ask is where this option indeed belongs to profile? My understanding here is that it indeed does, because incremental compilation could change the resulting artifact (i.e, LLVM may make different optimization decisions because of incremental).

Also, 🎉 🎊 🎆 🌠 🍒 🎉 🍕 🍍 !!!

@@ -157,21 +158,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
// Enable incremental builds if the user opts in. For now,
// this is an environment variable until things stabilize a
// bit more.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment can be deleted to avoid causing confusion.

// globally for a system configure whether incremental compilation is
// enabled. Note that setting this to `true` will not actually affect
// all builds though but instead only those profiles which would
// otherwise default to `true`. This can be useful to globally
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that setting this to true .. only those profiles which would otherwise default to true.

Should any of this say false instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm sorta, I reworded to hopefully make more sense.

@matklad matklad added the relnotes Release-note worthy label Dec 13, 2017
@matklad
Copy link
Member

matklad commented Dec 13, 2017

Oh, we might want to check how this interacts with cargo check just in case something gets broken.

@alexcrichton alexcrichton force-pushed the incremental-by-default branch 2 times, most recently from 26cfb4f to ea3b394 Compare December 14, 2017 05:07
@alexcrichton
Copy link
Member Author

@matklad

Let's add tests for profile and .cargo/config configuration?

Certainly! Should be done now.

A question I'd like to ask is where this option indeed belongs to profile?

Oh yeah incremental definitely affects compilation artifacts so we need to recompile whether it's on or off.

// all builds though. For example a `true` value doesn't enable
// release incremental builds, only dev incremental builds. This can
// be useful to globally disable incremental compilation like
// `CARGO_INCREMENTAL`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, so the value true for build.incremental does not change anything, because true && default is just default.

So, the only usage for this flag is to disable incremental compilation. So perhaps we can rename the flag to build.disable_incremental and allow only true value for it?

Should this setting override even explicit profile incremental setting? If the primary use-case here is to work-around the possible bugs in incremental compilation, then I think a reliable way to turn off all incremental would be more valuable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this was mostly just meant to mirror CARGO_INCREMENTAL as a "global configuration option" to disable it everywhere (I don't think enabling it everywhere makes much sense for release profiles for example).

I personally prefer incremental at least though to disable-incremental in that it's a bit more clear (even if incremental = true doesn't actually do anything).

I think that makes sense as well yeah for .cargo/config to override profiles, I'll tweak that

@lilianmoraru
Copy link

So, the only usage for this flag is to disable incremental compilation. So perhaps we can rename the flag to build.disable_incremental and allow only true value for it?

From a user's perspective(my personal perspective) that doesn't know what the code does behind, incremental just seems like the more obvious option that would enable or disable incremental compilation and of course, it is more in line with CARGO_INCREMENTAL.

@alexcrichton
Copy link
Member Author

Ok now that we've got a -C option upstream, re-r? @matklad

@matklad
Copy link
Member

matklad commented Dec 21, 2017

@alexcrichton should we add some docs here?

@alexcrichton alexcrichton force-pushed the incremental-by-default branch 2 times, most recently from b71594e to cf20cca Compare December 21, 2017 15:23
@alexcrichton
Copy link
Member Author

Seems plausible yeah, I've added some docs for the config key, env var, and profile option. I don't think we'll want to highlight it too much though (aka explain at length what the defaults are) as hopefully everyone's just going to see faster compiles :)

let global_cfg = self.config.get_bool("build.incremental")?.map(|c| c.val);
let profile = match unit.profile.incremental {
Incremental::Explicit(v) => v,
Incremental::Default(default) => default && global_cfg.unwrap_or(default),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I am staring at this boolean logic for like ten minutes, I can't persuade myself if it is right or wrong, could you recheck it just in case? :)

Here are my doubts:

I believe && global_cfg.unwrap_or(default) condition is not not necessary here. That is, if you remove it, the code would behave exactly the same.

  1. if global cfg is not set, then default && global_cfg.unpwrap_or(default) == default && default == default
  2. if global cfg is true, then default && global_cfg.unwrap_or(default) == default && true == default.
  3. if global cfg is false, than we'll bail out on the next like, without inspecting profile at all.

!self.incremental_env.unwrap_or(global_cfg.unwrap_or(profile))

So, if global_cfg is true, we do incremental regradless of profile setting? This is not what the doc comment says?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh oops, good catch!

The default here was intended to affect global_cfg, ensuring that if the default is false and the global cfg says true, we still turn it off. I'll update

};
if !self.incremental_env.unwrap_or(global_cfg.unwrap_or(profile)) {
return Ok(Vec::new())
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably just nitpicking, but I don't find this "nah, let's make global_cfg mutable" approach easy to follow :)

May I suggest the following match instead?

let incremental = match (self.incremental_env, global.cfg, unit.profile.incremental) {
    (Some(v), _, _) => v,
    (None, Some(false), _) => false,
    (None, _, Incremental::Explicit(v)) | 
    (None, _, Incremental::Default(v)) => v,
};

if !incremental {
    return Ok(Vec::new())
}

And looks like we perhaps we can get rid of distinction between Incremental::Explicit and Incremental::Default?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh excellent points! Updated now!

@matklad
Copy link
Member

matklad commented Dec 21, 2017

@bors r!

Excellent! 🚀

@matklad
Copy link
Member

matklad commented Dec 21, 2017

@bors r+

Robots are too unemotional :(

@bors
Copy link
Collaborator

bors commented Dec 21, 2017

📌 Commit 475fa58 has been approved by matklad

@bors
Copy link
Collaborator

bors commented Dec 21, 2017

⌛ Testing commit 475fa58115a615acc46966b60b69f4f13e14c05c with merge 203edeaf3cf3329611d7de5f2b71c158ea51d93f...

@bors
Copy link
Collaborator

bors commented Dec 21, 2017

💔 Test failed - status-travis

@matklad
Copy link
Member

matklad commented Dec 21, 2017

Test failure seems legit!

https://travis-ci.org/rust-lang/cargo/jobs/319850166#L1162

This commit enables incremental compilation by default in Cargo for all
dev-related profiles (aka anything without `--release` or `bench`. A
number of new configuration options were also added to tweak how
incremental compilation is exposed and/or used:

* A `profile.dev.incremental` field is added to `Cargo.toml` to disable
  it on a per-project basis (in case of bugs).
* A `build.incremental` field was added in `.cargo/config` to disable
  globally (or enable if we flip this default back off).

Otherwise `CARGO_INCREMENTAL` can still be used to configure one
particular compilation. The global `build.incremental` configuration
cannot currently be used to enable it for the release profile.
@alexcrichton
Copy link
Member Author

@bors: r=matklad

@bors
Copy link
Collaborator

bors commented Dec 21, 2017

📌 Commit 45cc30b has been approved by matklad

@bors
Copy link
Collaborator

bors commented Dec 21, 2017

⌛ Testing commit 45cc30b with merge e10c651...

bors added a commit that referenced this pull request Dec 21, 2017
Enable incremental by default

This commit enables incremental compilation by default in Cargo for all
dev-related profiles (aka anything without `--release` or `bench`. A
number of new configuration options were also added to tweak how
incremental compilation is exposed and/or used:

* A `profile.dev.incremental` field is added to `Cargo.toml` to disable
  it on a per-project basis (in case of bugs).
* A `build.incremental` field was added in `.cargo/config` to disable
  globally (or enable if we flip this default back off).

Otherwise `CARGO_INCREMENTAL` can still be used to configure one
particular compilation. The global `build.incremental` configuration
cannot currently be used to enable it for the release profile.
@bors
Copy link
Collaborator

bors commented Dec 21, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: matklad
Pushing e10c651 to master...

@bors bors merged commit 45cc30b into rust-lang:master Dec 21, 2017
@aidanhs
Copy link
Member

aidanhs commented Jan 9, 2018

As a point of interest, some (single binary) projects I'm looking at see a ~10% increase in the size of the target directory to store incremental things (~150MB in incremental dir, ~1.1GB overall).

Projects with more binaries will presumably see more impact, and things like crater (which build every single crate individually) see approximately a doubling of target dir size.

@michaelwoerister
Copy link
Member

Good to know, @aidanhs! A doubling of size is to be expected since we are basically keeping around a second version of the program in the incr. comp. cache. If it were much more than double, then that would be an indicator that cache garbage collection doesn't work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
relnotes Release-note worthy
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants