pub struct Profile {
pub opt_level: String,
#[serde(skip_serializing)]
- pub lto: bool,
+ pub lto: Lto,
#[serde(skip_serializing)]
pub codegen_units: Option<u32>, // None = use rustc default
#[serde(skip_serializing)]
pub incremental: bool,
}
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum Lto {
+ Bool(bool),
+ Named(String),
+}
+
#[derive(Default, Clone, Debug, PartialEq, Eq)]
pub struct Profiles {
pub release: Profile,
fn default() -> Profile {
Profile {
opt_level: "0".to_string(),
- lto: false,
+ lto: Lto::Bool(false),
codegen_units: None,
rustc_args: None,
rustdoc_args: None,
use core::{Package, PackageId, PackageSet, Target, Resolve};
use core::{Profile, Profiles, Workspace};
+use core::manifest::Lto;
use core::shell::ColorChoice;
use util::{self, ProcessBuilder, machine_message};
use util::{Config, internal, profile, join_paths};
unit: &Unit<'a>,
crate_types: &[&str]) -> CargoResult<()> {
let Profile {
- ref opt_level, lto, codegen_units, ref rustc_args, debuginfo,
+ ref opt_level, ref lto, codegen_units, ref rustc_args, debuginfo,
debug_assertions, overflow_checks, rpath, test, doc: _doc,
run_custom_build, ref panic, rustdoc_args: _, check, incremental: _,
} = *unit.profile;
// Disable LTO for host builds as prefer_dynamic and it are mutually
// exclusive.
- if unit.target.can_lto() && lto && !unit.target.for_host() {
- cmd.args(&["-C", "lto"]);
- } else if let Some(n) = codegen_units {
+ if unit.target.can_lto() && !unit.target.for_host() {
+ match *lto {
+ Lto::Bool(false) => {}
+ Lto::Bool(true) => {
+ cmd.args(&["-C", "lto"]);
+ }
+ Lto::Named(ref s) => {
+ cmd.arg("-C").arg(format!("lto={}", s));
+ }
+ }
+ }
+
+ if let Some(n) = codegen_units {
// There are some restrictions with LTO and codegen-units, so we
// only add codegen units when LTO is not used.
cmd.arg("-C").arg(&format!("codegen-units={}", n));
use core::{Summary, Manifest, Target, Dependency, PackageId};
use core::{EitherManifest, VirtualManifest, Features, Feature};
use core::dependency::{Kind, Platform};
-use core::manifest::{LibKind, Profile, ManifestMetadata};
+use core::manifest::{LibKind, Profile, ManifestMetadata, Lto};
use sources::CRATES_IO;
use util::paths;
use util::{self, ToUrl, Config};
pub struct TomlProfile {
#[serde(rename = "opt-level")]
opt_level: Option<TomlOptLevel>,
- lto: Option<bool>,
+ lto: Option<StringOrBool>,
#[serde(rename = "codegen-units")]
codegen_units: Option<u32>,
debug: Option<U32OrBool>,
fn merge(profile: Profile, toml: Option<&TomlProfile>) -> Profile {
let &TomlProfile {
- ref opt_level, lto, codegen_units, ref debug, debug_assertions, rpath,
+ ref opt_level, ref lto, codegen_units, ref debug, debug_assertions, rpath,
ref panic, ref overflow_checks, ref incremental,
} = match toml {
Some(toml) => toml,
};
Profile {
opt_level: opt_level.clone().unwrap_or(TomlOptLevel(profile.opt_level)).0,
- lto: lto.unwrap_or(profile.lto),
+ lto: match *lto {
+ Some(StringOrBool::Bool(b)) => Lto::Bool(b),
+ Some(StringOrBool::String(ref n)) => Lto::Named(n.clone()),
+ None => profile.lto,
+ },
codegen_units: codegen_units,
rustc_args: None,
rustdoc_args: None,
assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
}
+
+#[test]
+fn thin_lto_works() {
+ if !cargotest::is_nightly() {
+ return
+ }
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "top"
+ version = "0.5.0"
+ authors = []
+
+ [profile.release]
+ lto = 'thin'
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ assert_that(p.cargo("build").arg("--release").arg("-v"),
+ execs().with_stderr("\
+[COMPILING] top [..]
+[RUNNING] `rustc [..] -C lto=thin [..]`
+[FINISHED] [..]
+"));
+}