X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fbootstrap%2Fconfig.rs;h=7e6eecaaa884f5f4102aeb50c1f448bab7c03479;hb=88609e51265a563552e8fb4509f83a99e15451b2;hp=b17b94f2893953a2cfa69ac79437ce7178e05fab;hpb=2631aeef823a9e16d31f999d3f07001e5fcc4b3d;p=rust.git diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index b17b94f2893..7e6eecaaa88 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -6,7 +6,6 @@ use std::cmp; use std::collections::{HashMap, HashSet}; use std::env; -use std::ffi::OsString; use std::fmt; use std::fs; use std::path::{Path, PathBuf}; @@ -363,11 +362,13 @@ fn do_merge(x: &mut Option, y: Option) { // We are using a decl macro instead of a derive proc macro here to reduce the compile time of // rustbuild. -macro_rules! derive_merge { +macro_rules! define_config { ($(#[$attr:meta])* struct $name:ident { $($field:ident: $field_ty:ty,)* }) => { $(#[$attr])* + #[derive(Deserialize)] + #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct $name { $($field: $field_ty,)* } @@ -384,15 +385,13 @@ fn merge(&mut self, other: Self) { } } -derive_merge! { +define_config! { /// TOML representation of various global build decisions. - #[derive(Deserialize, Default)] - #[serde(deny_unknown_fields, rename_all = "kebab-case")] + #[derive(Default)] struct Build { build: Option, host: Option>, target: Option>, - // This is ignored, the rust code always gets the build directory from the `BUILD_DIR` env variable build_dir: Option, cargo: Option, rustc: Option, @@ -431,10 +430,8 @@ struct Build { } } -derive_merge! { +define_config! { /// TOML representation of various global install decisions. - #[derive(Deserialize)] - #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct Install { prefix: Option, sysconfdir: Option, @@ -446,10 +443,8 @@ struct Install { } } -derive_merge! { +define_config! { /// TOML representation of how the LLVM build is configured. - #[derive(Deserialize)] - #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct Llvm { skip_rebuild: Option, optimize: Option, @@ -481,9 +476,7 @@ struct Llvm { } } -derive_merge! { - #[derive(Deserialize)] - #[serde(deny_unknown_fields, rename_all = "kebab-case")] +define_config! { struct Dist { sign_folder: Option, gpg_password_file: Option, @@ -507,10 +500,8 @@ fn default() -> StringOrBool { } } -derive_merge! { +define_config! { /// TOML representation of how the Rust build is configured. - #[derive(Deserialize)] - #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct Rust { optimize: Option, debug: Option, @@ -562,10 +553,8 @@ struct Rust { } } -derive_merge! { +define_config! { /// TOML representation of how each build target is configured. - #[derive(Deserialize)] - #[serde(deny_unknown_fields, rename_all = "kebab-case")] struct TomlTarget { cc: Option, cxx: Option, @@ -588,18 +577,6 @@ struct TomlTarget { } impl Config { - fn path_from_python(var_key: &str) -> PathBuf { - match env::var_os(var_key) { - Some(var_val) => Self::normalize_python_path(var_val), - _ => panic!("expected '{}' to be set", var_key), - } - } - - /// Normalizes paths from Python slightly. We don't trust paths from Python (#49785). - fn normalize_python_path(path: OsString) -> PathBuf { - Path::new(&path).components().collect() - } - pub fn default_opts() -> Config { let mut config = Config::default(); config.llvm_optimize = true; @@ -625,7 +602,7 @@ pub fn default_opts() -> Config { let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); // Undo `src/bootstrap` config.src = manifest_dir.parent().unwrap().parent().unwrap().to_owned(); - config.out = Config::path_from_python("BUILD_DIR"); + config.out = PathBuf::from("build"); config.initial_cargo = PathBuf::from(env!("CARGO")); config.initial_rustc = PathBuf::from(env!("RUSTC")); @@ -655,19 +632,14 @@ pub fn parse(args: &[String]) -> Config { config.llvm_profile_use = flags.llvm_profile_use; config.llvm_profile_generate = flags.llvm_profile_generate; - if config.dry_run { - let dir = config.out.join("tmp-dry-run"); - t!(fs::create_dir_all(&dir)); - config.out = dir; - } - #[cfg(test)] let get_toml = |_| TomlConfig::default(); #[cfg(not(test))] let get_toml = |file: &Path| { use std::process; - let contents = t!(fs::read_to_string(file), "`include` config not found"); + let contents = + t!(fs::read_to_string(file), format!("config file {} not found", file.display())); match toml::from_str(&contents) { Ok(table) => table, Err(err) => { @@ -677,7 +649,25 @@ pub fn parse(args: &[String]) -> Config { } }; - let mut toml = flags.config.as_deref().map(get_toml).unwrap_or_else(TomlConfig::default); + // Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory. + let toml_path = flags + .config + .clone() + .or_else(|| env::var_os("RUST_BOOTSTRAP_CONFIG").map(PathBuf::from)); + let using_default_path = toml_path.is_none(); + let mut toml_path = toml_path.unwrap_or_else(|| PathBuf::from("config.toml")); + if using_default_path && !toml_path.exists() { + toml_path = config.src.join(toml_path); + } + + // Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path, + // but not if `config.toml` hasn't been created. + let mut toml = if !using_default_path || toml_path.exists() { + get_toml(&toml_path) + } else { + TomlConfig::default() + }; + if let Some(include) = &toml.profile { let mut include_path = config.src.clone(); include_path.push("src"); @@ -689,12 +679,25 @@ pub fn parse(args: &[String]) -> Config { } config.changelog_seen = toml.changelog_seen; - if let Some(cfg) = flags.config { - config.config = cfg; - } + config.config = toml_path; let build = toml.build.unwrap_or_default(); + set(&mut config.initial_rustc, build.rustc.map(PathBuf::from)); + set(&mut config.out, build.build_dir.map(PathBuf::from)); + // NOTE: Bootstrap spawns various commands with different working directories. + // To avoid writing to random places on the file system, `config.out` needs to be an absolute path. + if !config.out.is_absolute() { + // `canonicalize` requires the path to already exist. Use our vendored copy of `absolute` instead. + config.out = crate::util::absolute(&config.out); + } + + if config.dry_run { + let dir = config.out.join("tmp-dry-run"); + t!(fs::create_dir_all(&dir)); + config.out = dir; + } + config.hosts = if let Some(arg_host) = flags.host { arg_host } else if let Some(file_host) = build.host {