Skip to content

Commit 90f8274

Browse files
committed
Auto merge of #4984 - alexcrichton:configure-lto, r=matklad
Allow configuration of LTO in [profile] This should help give access to ThinLTO when desired!
2 parents 1c3f33b + f52f489 commit 90f8274

File tree

4 files changed

+57
-10
lines changed

4 files changed

+57
-10
lines changed

src/cargo/core/manifest.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl ser::Serialize for TargetKind {
156156
pub struct Profile {
157157
pub opt_level: String,
158158
#[serde(skip_serializing)]
159-
pub lto: bool,
159+
pub lto: Lto,
160160
#[serde(skip_serializing)]
161161
pub codegen_units: Option<u32>, // None = use rustc default
162162
#[serde(skip_serializing)]
@@ -181,6 +181,12 @@ pub struct Profile {
181181
pub incremental: bool,
182182
}
183183

184+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
185+
pub enum Lto {
186+
Bool(bool),
187+
Named(String),
188+
}
189+
184190
#[derive(Default, Clone, Debug, PartialEq, Eq)]
185191
pub struct Profiles {
186192
pub release: Profile,
@@ -702,7 +708,7 @@ impl Default for Profile {
702708
fn default() -> Profile {
703709
Profile {
704710
opt_level: "0".to_string(),
705-
lto: false,
711+
lto: Lto::Bool(false),
706712
codegen_units: None,
707713
rustc_args: None,
708714
rustdoc_args: None,

src/cargo/ops/cargo_rustc/mod.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use serde_json;
1111

1212
use core::{Package, PackageId, PackageSet, Target, Resolve};
1313
use core::{Profile, Profiles, Workspace};
14+
use core::manifest::Lto;
1415
use core::shell::ColorChoice;
1516
use util::{self, ProcessBuilder, machine_message};
1617
use util::{Config, internal, profile, join_paths};
@@ -744,7 +745,7 @@ fn build_base_args<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
744745
unit: &Unit<'a>,
745746
crate_types: &[&str]) -> CargoResult<()> {
746747
let Profile {
747-
ref opt_level, lto, codegen_units, ref rustc_args, debuginfo,
748+
ref opt_level, ref lto, codegen_units, ref rustc_args, debuginfo,
748749
debug_assertions, overflow_checks, rpath, test, doc: _doc,
749750
run_custom_build, ref panic, rustdoc_args: _, check, incremental: _,
750751
} = *unit.profile;
@@ -806,9 +807,19 @@ fn build_base_args<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
806807

807808
// Disable LTO for host builds as prefer_dynamic and it are mutually
808809
// exclusive.
809-
if unit.target.can_lto() && lto && !unit.target.for_host() {
810-
cmd.args(&["-C", "lto"]);
811-
} else if let Some(n) = codegen_units {
810+
if unit.target.can_lto() && !unit.target.for_host() {
811+
match *lto {
812+
Lto::Bool(false) => {}
813+
Lto::Bool(true) => {
814+
cmd.args(&["-C", "lto"]);
815+
}
816+
Lto::Named(ref s) => {
817+
cmd.arg("-C").arg(format!("lto={}", s));
818+
}
819+
}
820+
}
821+
822+
if let Some(n) = codegen_units {
812823
// There are some restrictions with LTO and codegen-units, so we
813824
// only add codegen units when LTO is not used.
814825
cmd.arg("-C").arg(&format!("codegen-units={}", n));

src/cargo/util/toml/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use core::{SourceId, Profiles, PackageIdSpec, GitReference, WorkspaceConfig, Wor
1616
use core::{Summary, Manifest, Target, Dependency, PackageId};
1717
use core::{EitherManifest, VirtualManifest, Features, Feature};
1818
use core::dependency::{Kind, Platform};
19-
use core::manifest::{LibKind, Profile, ManifestMetadata};
19+
use core::manifest::{LibKind, Profile, ManifestMetadata, Lto};
2020
use sources::CRATES_IO;
2121
use util::paths;
2222
use util::{self, ToUrl, Config};
@@ -327,7 +327,7 @@ impl<'de> de::Deserialize<'de> for U32OrBool {
327327
pub struct TomlProfile {
328328
#[serde(rename = "opt-level")]
329329
opt_level: Option<TomlOptLevel>,
330-
lto: Option<bool>,
330+
lto: Option<StringOrBool>,
331331
#[serde(rename = "codegen-units")]
332332
codegen_units: Option<u32>,
333333
debug: Option<U32OrBool>,
@@ -1150,7 +1150,7 @@ fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
11501150

11511151
fn merge(profile: Profile, toml: Option<&TomlProfile>) -> Profile {
11521152
let &TomlProfile {
1153-
ref opt_level, lto, codegen_units, ref debug, debug_assertions, rpath,
1153+
ref opt_level, ref lto, codegen_units, ref debug, debug_assertions, rpath,
11541154
ref panic, ref overflow_checks, ref incremental,
11551155
} = match toml {
11561156
Some(toml) => toml,
@@ -1164,7 +1164,11 @@ fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
11641164
};
11651165
Profile {
11661166
opt_level: opt_level.clone().unwrap_or(TomlOptLevel(profile.opt_level)).0,
1167-
lto: lto.unwrap_or(profile.lto),
1167+
lto: match *lto {
1168+
Some(StringOrBool::Bool(b)) => Lto::Bool(b),
1169+
Some(StringOrBool::String(ref n)) => Lto::Named(n.clone()),
1170+
None => profile.lto,
1171+
},
11681172
codegen_units: codegen_units,
11691173
rustc_args: None,
11701174
rustdoc_args: None,

tests/path.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,3 +986,29 @@ fn workspace_produces_rlib() {
986986
assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
987987

988988
}
989+
990+
#[test]
991+
fn thin_lto_works() {
992+
if !cargotest::is_nightly() {
993+
return
994+
}
995+
let p = project("foo")
996+
.file("Cargo.toml", r#"
997+
[project]
998+
name = "top"
999+
version = "0.5.0"
1000+
authors = []
1001+
1002+
[profile.release]
1003+
lto = 'thin'
1004+
"#)
1005+
.file("src/main.rs", "fn main() {}")
1006+
.build();
1007+
1008+
assert_that(p.cargo("build").arg("--release").arg("-v"),
1009+
execs().with_stderr("\
1010+
[COMPILING] top [..]
1011+
[RUNNING] `rustc [..] -C lto=thin [..]`
1012+
[FINISHED] [..]
1013+
"));
1014+
}

0 commit comments

Comments
 (0)