@@ -100,7 +100,7 @@ pub struct Context<'a, 'cfg: 'a> {
100
100
target_info : TargetInfo ,
101
101
host_info : TargetInfo ,
102
102
profiles : & ' a Profiles ,
103
- incremental_enabled : bool ,
103
+ incremental_env : Option < bool > ,
104
104
105
105
/// For each Unit, a list all files produced as a triple of
106
106
///
@@ -154,24 +154,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
154
154
None => None ,
155
155
} ;
156
156
157
- // Enable incremental builds if the user opts in. For now,
158
- // this is an environment variable until things stabilize a
159
- // bit more.
160
- let incremental_enabled = match env:: var ( "CARGO_INCREMENTAL" ) {
161
- Ok ( v) => v == "1" ,
162
- Err ( _) => false ,
157
+ let incremental_env = match env:: var ( "CARGO_INCREMENTAL" ) {
158
+ Ok ( v) => Some ( v == "1" ) ,
159
+ Err ( _) => None ,
163
160
} ;
164
161
165
- // -Z can only be used on nightly builds; other builds complain loudly.
166
- // Since incremental builds only work on nightly anyway, we silently
167
- // ignore CARGO_INCREMENTAL on anything but nightly. This allows users
168
- // to always have CARGO_INCREMENTAL set without getting unexpected
169
- // errors on stable/beta builds.
170
- let is_nightly =
171
- config. rustc ( ) ?. verbose_version . contains ( "-nightly" ) ||
172
- config. rustc ( ) ?. verbose_version . contains ( "-dev" ) ;
173
- let incremental_enabled = incremental_enabled && is_nightly;
174
-
175
162
// Load up the jobserver that we'll use to manage our parallelism. This
176
163
// is the same as the GNU make implementation of a jobserver, and
177
164
// intentionally so! It's hoped that we can interact with GNU make and
@@ -206,7 +193,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
206
193
build_explicit_deps : HashMap :: new ( ) ,
207
194
links : Links :: new ( ) ,
208
195
used_in_plugin : HashSet :: new ( ) ,
209
- incremental_enabled : incremental_enabled ,
196
+ incremental_env ,
210
197
jobserver : jobserver,
211
198
build_script_overridden : HashSet :: new ( ) ,
212
199
@@ -1082,24 +1069,53 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
1082
1069
}
1083
1070
1084
1071
pub fn incremental_args ( & self , unit : & Unit ) -> CargoResult < Vec < String > > {
1085
- if self . incremental_enabled {
1086
- if unit. pkg . package_id ( ) . source_id ( ) . is_path ( ) {
1087
- // Only enable incremental compilation for sources the user can modify.
1088
- // For things that change infrequently, non-incremental builds yield
1089
- // better performance.
1090
- // (see also https://github.com/rust-lang/cargo/issues/3972)
1091
- return Ok ( vec ! [ format!( "-Zincremental={}" ,
1092
- self . layout( unit. kind) . incremental( ) . display( ) ) ] ) ;
1093
- } else if unit. profile . codegen_units . is_none ( ) {
1094
- // For non-incremental builds we set a higher number of
1095
- // codegen units so we get faster compiles. It's OK to do
1096
- // so because the user has already opted into slower
1097
- // runtime code by setting CARGO_INCREMENTAL.
1098
- return Ok ( vec ! [ format!( "-Ccodegen-units={}" , :: num_cpus:: get( ) ) ] ) ;
1099
- }
1072
+ // There's a number of ways to configure incremental compilation right
1073
+ // now. In order of descending priority (first is highest priority) we
1074
+ // have:
1075
+ //
1076
+ // * `CARGO_INCREMENTAL` - this is blanket used unconditionally to turn
1077
+ // on/off incremental compilation for any cargo subcommand. We'll
1078
+ // respect this if set.
1079
+ // * `build.incremental` - in `.cargo/config` this blanket key can
1080
+ // globally for a system configure whether incremental compilation is
1081
+ // enabled. Note that setting this to `true` will not actually affect
1082
+ // all builds though. For example a `true` value doesn't enable
1083
+ // release incremental builds, only dev incremental builds. This can
1084
+ // be useful to globally disable incremental compilation like
1085
+ // `CARGO_INCREMENTAL`.
1086
+ // * `profile.dev.incremental` - in `Cargo.toml` specific profiles can
1087
+ // be configured to enable/disable incremental compilation. This can
1088
+ // be primarily used to disable incremental when buggy for a project.
1089
+ // * Finally, each profile has a default for whether it will enable
1090
+ // incremental compilation or not. Primarily development profiles
1091
+ // have it enabled by default while release profiles have it disabled
1092
+ // by default.
1093
+ let global_cfg = self . config . get_bool ( "build.incremental" ) ?. map ( |c| c. val ) ;
1094
+ let incremental = match ( self . incremental_env , global_cfg, unit. profile . incremental ) {
1095
+ ( Some ( v) , _, _) => v,
1096
+ ( None , Some ( false ) , _) => false ,
1097
+ ( None , _, other) => other,
1098
+ } ;
1099
+
1100
+ if !incremental {
1101
+ return Ok ( Vec :: new ( ) )
1102
+ }
1103
+
1104
+ // Only enable incremental compilation for sources the user can
1105
+ // modify (aka path sources). For things that change infrequently,
1106
+ // non-incremental builds yield better performance in the compiler
1107
+ // itself (aka crates.io / git dependencies)
1108
+ //
1109
+ // (see also https://github.com/rust-lang/cargo/issues/3972)
1110
+ if !unit. pkg . package_id ( ) . source_id ( ) . is_path ( ) {
1111
+ return Ok ( Vec :: new ( ) )
1100
1112
}
1101
1113
1102
- Ok ( vec ! [ ] )
1114
+ let dir = self . layout ( unit. kind ) . incremental ( ) . display ( ) ;
1115
+ Ok ( vec ! [
1116
+ "-C" . to_string( ) ,
1117
+ format!( "incremental={}" , dir) ,
1118
+ ] )
1103
1119
}
1104
1120
1105
1121
pub fn rustflags_args ( & self , unit : & Unit ) -> CargoResult < Vec < String > > {
0 commit comments