Skip to content

Commit

Permalink
Auto merge of #3007 - whitequark:opt-level-s, r=alexcrichton
Browse files Browse the repository at this point in the history
Allow using opt-level="s"/"z" in profile overrides

Initially, I've considered making a dedicated `OptLevel` enum, but this appeared to bring no practical benefit, only boilerplate, so I've used a String instead, which is also in line with the `u32` that was there before, not even checked for being in range `0...3`.
  • Loading branch information
bors authored Aug 18, 2016
2 parents 4c21961 + bc858b0 commit 22fccc1
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 13 deletions.
6 changes: 3 additions & 3 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl Encodable for TargetKind {

#[derive(RustcEncodable, RustcDecodable, Clone, PartialEq, Eq, Debug, Hash)]
pub struct Profile {
pub opt_level: u32,
pub opt_level: String,
pub lto: bool,
pub codegen_units: Option<u32>, // None = use rustc default
pub rustc_args: Option<Vec<String>>,
Expand Down Expand Up @@ -473,7 +473,7 @@ impl Profile {

pub fn default_release() -> Profile {
Profile {
opt_level: 3,
opt_level: "3".to_string(),
debuginfo: false,
..Profile::default()
}
Expand Down Expand Up @@ -511,7 +511,7 @@ impl Profile {
impl Default for Profile {
fn default() -> Profile {
Profile {
opt_level: 0,
opt_level: "0".to_string(),
lto: false,
codegen_units: None,
rustc_args: None,
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_rustc/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
Kind::Target => cx.target_triple(),
})
.env("DEBUG", &profile.debuginfo.to_string())
.env("OPT_LEVEL", &profile.opt_level.to_string())
.env("OPT_LEVEL", &profile.opt_level)
.env("PROFILE", if cx.build_config.release {"release"} else {"debug"})
.env("HOST", cx.host_triple())
.env("RUSTC", &try!(cx.config.rustc()).path)
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/ops/cargo_rustc/job_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ impl<'a> JobQueue<'a> {

let build_type = if self.is_release { "release" } else { "debug" };
let profile = cx.lib_profile(cx.resolve.root());
let mut opt_type = String::from(if profile.opt_level > 0 { "optimized" }
else { "unoptimized" });
let mut opt_type = String::from(if profile.opt_level == "0" { "unoptimized" }
else { "optimized" });
if profile.debuginfo {
opt_type = opt_type + " + debuginfo";
}
Expand Down
8 changes: 4 additions & 4 deletions src/cargo/ops/cargo_rustc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ fn build_base_args(cx: &Context,
unit: &Unit,
crate_types: &[&str]) {
let Profile {
opt_level, lto, codegen_units, ref rustc_args, debuginfo,
ref opt_level, lto, codegen_units, ref rustc_args, debuginfo,
debug_assertions, rpath, test, doc: _doc, run_custom_build,
ref panic, rustdoc_args: _,
} = *unit.profile;
Expand Down Expand Up @@ -509,7 +509,7 @@ fn build_base_args(cx: &Context,
cmd.arg("-C").arg("prefer-dynamic");
}

if opt_level != 0 {
if opt_level != "0" {
cmd.arg("-C").arg(&format!("opt-level={}", opt_level));
}

Expand Down Expand Up @@ -549,9 +549,9 @@ fn build_base_args(cx: &Context,
cmd.args(args);
}

if debug_assertions && opt_level > 0 {
if debug_assertions && opt_level != "0" {
cmd.args(&["-C", "debug-assertions=on"]);
} else if !debug_assertions && opt_level == 0 {
} else if !debug_assertions && opt_level == "0" {
cmd.args(&["-C", "debug-assertions=off"]);
}

Expand Down
25 changes: 22 additions & 3 deletions src/cargo/util/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,28 @@ pub struct TomlProfiles {
release: Option<TomlProfile>,
}

#[derive(Clone)]
pub struct TomlOptLevel(String);

impl Decodable for TomlOptLevel {
fn decode<D: Decoder>(d: &mut D) -> Result<TomlOptLevel, D::Error> {
match d.read_u32() {
Ok(i) => Ok(TomlOptLevel(i.to_string())),
Err(_) => {
match d.read_str() {
Ok(ref s) if s == "s" || s == "z" =>
Ok(TomlOptLevel(s.to_string())),
Ok(_) | Err(_) =>
Err(d.error("expected an integer, a string \"z\" or a string \"s\""))
}
}
}
}
}

#[derive(RustcDecodable, Clone, Default)]
pub struct TomlProfile {
opt_level: Option<u32>,
opt_level: Option<TomlOptLevel>,
lto: Option<bool>,
codegen_units: Option<u32>,
debug: Option<bool>,
Expand Down Expand Up @@ -1188,14 +1207,14 @@ fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {

fn merge(profile: Profile, toml: Option<&TomlProfile>) -> Profile {
let &TomlProfile {
opt_level, lto, codegen_units, debug, debug_assertions, rpath,
ref opt_level, lto, codegen_units, debug, debug_assertions, rpath,
ref panic
} = match toml {
Some(toml) => toml,
None => return profile,
};
Profile {
opt_level: opt_level.unwrap_or(profile.opt_level),
opt_level: opt_level.clone().unwrap_or(TomlOptLevel(profile.opt_level)).0,
lto: lto.unwrap_or(profile.lto),
codegen_units: codegen_units,
rustc_args: None,
Expand Down
80 changes: 80 additions & 0 deletions tests/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ extern crate hamcrest;
use std::env;
use std::path::MAIN_SEPARATOR as SEP;

use cargotest::is_nightly;
use cargotest::support::{project, execs};
use hamcrest::assert_that;

Expand Down Expand Up @@ -42,6 +43,85 @@ url = p.url(),
)));
}

#[test]
fn opt_level_override_0() {
let mut p = project("foo");
p = p
.file("Cargo.toml", r#"
[package]
name = "test"
version = "0.0.0"
authors = []
[profile.dev]
opt-level = 0
"#)
.file("src/lib.rs", "");
assert_that(p.cargo_process("build").arg("-v"),
execs().with_status(0).with_stderr(&format!("\
[COMPILING] test v0.0.0 ({url})
[RUNNING] `rustc src{sep}lib.rs --crate-name test --crate-type lib \
-g \
-C metadata=[..] \
--out-dir [..] \
--emit=dep-info,link \
-L dependency={dir}{sep}target{sep}debug{sep}deps`
[FINISHED] [..] target(s) in [..]
", sep = SEP,
dir = p.root().display(),
url = p.url()
)));
}

fn check_opt_level_override(profile_level: &str, rustc_level: &str) {
let mut p = project("foo");
p = p
.file("Cargo.toml", &format!(r#"
[package]
name = "test"
version = "0.0.0"
authors = []
[profile.dev]
opt-level = {level}
"#, level = profile_level))
.file("src/lib.rs", "");
assert_that(p.cargo_process("build").arg("-v"),
execs().with_status(0).with_stderr(&format!("\
[COMPILING] test v0.0.0 ({url})
[RUNNING] `rustc src{sep}lib.rs --crate-name test --crate-type lib \
-C opt-level={level} \
-g \
-C debug-assertions=on \
-C metadata=[..] \
--out-dir [..] \
--emit=dep-info,link \
-L dependency={dir}{sep}target{sep}debug{sep}deps`
[FINISHED] [..] target(s) in [..]
", sep = SEP,
dir = p.root().display(),
url = p.url(),
level = rustc_level
)));
}

#[test]
fn opt_level_overrides() {
if !is_nightly() { return }

for &(profile_level, rustc_level) in &[
("1", "1"),
("2", "2"),
("3", "3"),
("\"s\"", "s"),
("\"z\"", "z"),
] {
check_opt_level_override(profile_level, rustc_level)
}
}

#[test]
fn top_level_overrides_deps() {
let mut p = project("foo");
Expand Down

0 comments on commit 22fccc1

Please sign in to comment.