From e6e2825bb018baa4f0f6dfecd4206beb73d3ebf4 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Sun, 18 Jun 2023 14:38:58 +0800 Subject: [PATCH 1/3] Use RustOptimize to set optimize Signed-off-by: hi-rustin --- src/bootstrap/builder.rs | 7 ++++-- src/bootstrap/config.rs | 48 +++++++++++++++++++++++++++++++++++----- src/bootstrap/lib.rs | 2 +- src/bootstrap/test.rs | 2 +- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index a1d3453377ab0..05b66f94727ad 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1207,7 +1207,7 @@ impl<'a> Builder<'a> { assert_eq!(target, compiler.host); } - if self.config.rust_optimize { + if self.config.rust_optimize.is_release() { // FIXME: cargo bench/install do not accept `--release` if cmd != "bench" && cmd != "install" { cargo.arg("--release"); @@ -1263,7 +1263,7 @@ impl<'a> Builder<'a> { } let profile_var = |name: &str| { - let profile = if self.config.rust_optimize { "RELEASE" } else { "DEV" }; + let profile = if self.config.rust_optimize.is_release() { "RELEASE" } else { "DEV" }; format!("CARGO_PROFILE_{}_{}", profile, name) }; @@ -1652,6 +1652,9 @@ impl<'a> Builder<'a> { } }; cargo.env(profile_var("DEBUG"), debuginfo_level.to_string()); + if let Some(opt_level) = &self.config.rust_optimize.get_opt_level() { + cargo.env(profile_var("OPT_LEVEL"), opt_level); + } if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz") { rustflags.arg("-Clink-arg=-gz"); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index b91275e73e9c4..5a0e5d2081812 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -202,7 +202,7 @@ pub struct Config { pub llvm_use_libcxx: bool, // rust codegen options - pub rust_optimize: bool, + pub rust_optimize: RustOptimize, pub rust_codegen_units: Option, pub rust_codegen_units_std: Option, pub rust_debug_assertions: bool, @@ -875,17 +875,55 @@ impl Default for StringOrBool { } } +#[derive(Clone, Debug, Deserialize)] +#[serde(untagged)] +pub enum RustOptimize { + #[serde(deserialize_with = "deserialize_and_validate_opt_level")] + String(String), + Bool(bool), +} + +impl Default for RustOptimize { + fn default() -> RustOptimize { + RustOptimize::Bool(false) + } +} + +fn deserialize_and_validate_opt_level<'de, D>(d: D) -> Result +where + D: serde::de::Deserializer<'de>, +{ + let v = String::deserialize(d)?; + if ["0", "1", "2", "3", "s", "z"].iter().find(|x| **x == v).is_some() { + Ok(v) + } else { + Err(format!(r#"unrecognized option for rust optimize: "{}", expected one of "0", "1", "2", "3", "s", "z""#, v)).map_err(serde::de::Error::custom) + } +} + +impl RustOptimize { + pub(crate) fn is_release(&self) -> bool { + if let RustOptimize::Bool(true) | RustOptimize::String(_) = &self { true } else { false } + } + + pub(crate) fn get_opt_level(&self) -> Option { + match &self { + RustOptimize::String(s) => Some(s.clone()), + RustOptimize::Bool(_) => None, + } + } +} + #[derive(Deserialize)] #[serde(untagged)] enum StringOrInt<'a> { String(&'a str), Int(i64), } - define_config! { /// TOML representation of how the Rust build is configured. struct Rust { - optimize: Option = "optimize", + optimize: Option = "optimize", debug: Option = "debug", codegen_units: Option = "codegen-units", codegen_units_std: Option = "codegen-units-std", @@ -971,7 +1009,7 @@ impl Config { config.ninja_in_file = true; config.llvm_static_stdcpp = false; config.backtrace = true; - config.rust_optimize = true; + config.rust_optimize = RustOptimize::Bool(true); config.rust_optimize_tests = true; config.submodules = None; config.docs = true; @@ -1546,7 +1584,7 @@ impl Config { config.llvm_assertions = llvm_assertions.unwrap_or(false); config.llvm_tests = llvm_tests.unwrap_or(false); config.llvm_plugins = llvm_plugins.unwrap_or(false); - config.rust_optimize = optimize.unwrap_or(true); + config.rust_optimize = optimize.unwrap_or(RustOptimize::Bool(true)); let default = debug == Some(true); config.rust_debug_assertions = debug_assertions.unwrap_or(default); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index c960053d7a0f2..6a51450a777e8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -785,7 +785,7 @@ impl Build { /// Component directory that Cargo will produce output into (e.g. /// release/debug) fn cargo_dir(&self) -> &'static str { - if self.config.rust_optimize { "release" } else { "debug" } + if self.config.rust_optimize.is_release() { "release" } else { "debug" } } fn tools_dir(&self, compiler: Compiler) -> PathBuf { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 2c1f612e39f52..a2938ab4caf37 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -801,7 +801,7 @@ impl Step for Clippy { cargo.arg("-p").arg("clippy_dev"); // clippy_dev gets confused if it can't find `clippy/Cargo.toml` cargo.current_dir(&builder.src.join("src").join("tools").join("clippy")); - if builder.config.rust_optimize { + if builder.config.rust_optimize.is_release() { cargo.env("PROFILE", "release"); } else { cargo.env("PROFILE", "debug"); From 878eff12074621e37bef8dabc85c5a8d312fd400 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Sat, 1 Jul 2023 16:59:35 +0800 Subject: [PATCH 2/3] Add tests for RustOptimize Signed-off-by: hi-rustin --- src/bootstrap/config.rs | 2 +- src/bootstrap/config/tests.rs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 5a0e5d2081812..5f5f7ea25fb95 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -875,7 +875,7 @@ impl Default for StringOrBool { } } -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum RustOptimize { #[serde(deserialize_with = "deserialize_and_validate_opt_level")] diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs index 3bee659abd1c5..6ec24530af2b4 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -178,3 +178,22 @@ fn profile_user_dist() { } Config::parse_inner(&["check".to_owned()], get_toml); } + +#[test] +fn rust_optimize() { + let parse = |s| Config::parse_inner(&["check".to_owned()], |&_| toml::from_str(s).unwrap()); + + assert_eq!(parse("").rust_optimize.is_release(), true); + assert_eq!(parse("rust.optimize = false").rust_optimize.is_release(), false); + assert_eq!(parse("rust.optimize = true").rust_optimize.is_release(), true); + assert_eq!(parse("rust.optimize = \"1\"").rust_optimize.get_opt_level(), Some("1".to_string())); + assert_eq!(parse("rust.optimize = \"s\"").rust_optimize.get_opt_level(), Some("s".to_string())); +} + +#[test] +#[should_panic] +fn invalid_rust_optimize() { + Config::parse_inner(&["check".to_owned()], |&_| { + toml::from_str("rust.optimize = \"a\"").unwrap() + }); +} From 7cab8f786280ab249d8e0711d085d853aa41629f Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Sun, 2 Jul 2023 12:07:25 +0800 Subject: [PATCH 3/3] Fix broken tests Signed-off-by: hi-rustin --- src/bootstrap/config/tests.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs index 6ec24530af2b4..732df54cdacbd 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -181,8 +181,6 @@ fn profile_user_dist() { #[test] fn rust_optimize() { - let parse = |s| Config::parse_inner(&["check".to_owned()], |&_| toml::from_str(s).unwrap()); - assert_eq!(parse("").rust_optimize.is_release(), true); assert_eq!(parse("rust.optimize = false").rust_optimize.is_release(), false); assert_eq!(parse("rust.optimize = true").rust_optimize.is_release(), true); @@ -193,7 +191,5 @@ fn rust_optimize() { #[test] #[should_panic] fn invalid_rust_optimize() { - Config::parse_inner(&["check".to_owned()], |&_| { - toml::from_str("rust.optimize = \"a\"").unwrap() - }); + parse("rust.optimize = \"a\""); }