|
3 | 3 | //! This module implements parsing `config.toml` configuration files to tweak
|
4 | 4 | //! how the build runs.
|
5 | 5 |
|
| 6 | +#[cfg(test)] |
| 7 | +mod tests; |
| 8 | + |
6 | 9 | use std::cell::{Cell, RefCell};
|
7 | 10 | use std::cmp;
|
8 | 11 | use std::collections::{HashMap, HashSet};
|
@@ -696,7 +699,7 @@ define_config! {
|
696 | 699 | }
|
697 | 700 | }
|
698 | 701 |
|
699 |
| -#[derive(Deserialize)] |
| 702 | +#[derive(Debug, Deserialize)] |
700 | 703 | #[serde(untagged)]
|
701 | 704 | enum StringOrBool {
|
702 | 705 | String(String),
|
@@ -822,6 +825,29 @@ impl Config {
|
822 | 825 | }
|
823 | 826 |
|
824 | 827 | pub fn parse(args: &[String]) -> Config {
|
| 828 | + #[cfg(test)] |
| 829 | + let get_toml = |_: &_| TomlConfig::default(); |
| 830 | + #[cfg(not(test))] |
| 831 | + let get_toml = |file: &Path| { |
| 832 | + let contents = |
| 833 | + t!(fs::read_to_string(file), format!("config file {} not found", file.display())); |
| 834 | + // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of |
| 835 | + // TomlConfig and sub types to be monomorphized 5x by toml. |
| 836 | + match toml::from_str(&contents) |
| 837 | + .and_then(|table: toml::Value| TomlConfig::deserialize(table)) |
| 838 | + { |
| 839 | + Ok(table) => table, |
| 840 | + Err(err) => { |
| 841 | + eprintln!("failed to parse TOML configuration '{}': {}", file.display(), err); |
| 842 | + crate::detail_exit(2); |
| 843 | + } |
| 844 | + } |
| 845 | + }; |
| 846 | + |
| 847 | + Self::parse_inner(args, get_toml) |
| 848 | + } |
| 849 | + |
| 850 | + fn parse_inner<'a>(args: &[String], get_toml: impl 'a + Fn(&Path) -> TomlConfig) -> Config { |
825 | 851 | let flags = Flags::parse(&args);
|
826 | 852 | let mut config = Config::default_opts();
|
827 | 853 |
|
@@ -907,25 +933,6 @@ impl Config {
|
907 | 933 |
|
908 | 934 | config.stage0_metadata = t!(serde_json::from_slice::<Stage0Metadata>(&stage0_json));
|
909 | 935 |
|
910 |
| - #[cfg(test)] |
911 |
| - let get_toml = |_| TomlConfig::default(); |
912 |
| - #[cfg(not(test))] |
913 |
| - let get_toml = |file: &Path| { |
914 |
| - let contents = |
915 |
| - t!(fs::read_to_string(file), format!("config file {} not found", file.display())); |
916 |
| - // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of |
917 |
| - // TomlConfig and sub types to be monomorphized 5x by toml. |
918 |
| - match toml::from_str(&contents) |
919 |
| - .and_then(|table: toml::Value| TomlConfig::deserialize(table)) |
920 |
| - { |
921 |
| - Ok(table) => table, |
922 |
| - Err(err) => { |
923 |
| - eprintln!("failed to parse TOML configuration '{}': {}", file.display(), err); |
924 |
| - crate::detail_exit(2); |
925 |
| - } |
926 |
| - } |
927 |
| - }; |
928 |
| - |
929 | 936 | // Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory.
|
930 | 937 | let toml_path = flags
|
931 | 938 | .config
|
@@ -1063,6 +1070,79 @@ impl Config {
|
1063 | 1070 | let mut optimize = None;
|
1064 | 1071 | let mut ignore_git = None;
|
1065 | 1072 |
|
| 1073 | + if let Some(rust) = toml.rust { |
| 1074 | + debug = rust.debug; |
| 1075 | + debug_assertions = rust.debug_assertions; |
| 1076 | + debug_assertions_std = rust.debug_assertions_std; |
| 1077 | + overflow_checks = rust.overflow_checks; |
| 1078 | + overflow_checks_std = rust.overflow_checks_std; |
| 1079 | + debug_logging = rust.debug_logging; |
| 1080 | + debuginfo_level = rust.debuginfo_level; |
| 1081 | + debuginfo_level_rustc = rust.debuginfo_level_rustc; |
| 1082 | + debuginfo_level_std = rust.debuginfo_level_std; |
| 1083 | + debuginfo_level_tools = rust.debuginfo_level_tools; |
| 1084 | + debuginfo_level_tests = rust.debuginfo_level_tests; |
| 1085 | + config.rust_split_debuginfo = rust |
| 1086 | + .split_debuginfo |
| 1087 | + .as_deref() |
| 1088 | + .map(SplitDebuginfo::from_str) |
| 1089 | + .map(|v| v.expect("invalid value for rust.split_debuginfo")) |
| 1090 | + .unwrap_or(SplitDebuginfo::default_for_platform(&config.build.triple)); |
| 1091 | + optimize = rust.optimize; |
| 1092 | + ignore_git = rust.ignore_git; |
| 1093 | + config.rust_new_symbol_mangling = rust.new_symbol_mangling; |
| 1094 | + set(&mut config.rust_optimize_tests, rust.optimize_tests); |
| 1095 | + set(&mut config.codegen_tests, rust.codegen_tests); |
| 1096 | + set(&mut config.rust_rpath, rust.rpath); |
| 1097 | + set(&mut config.jemalloc, rust.jemalloc); |
| 1098 | + set(&mut config.test_compare_mode, rust.test_compare_mode); |
| 1099 | + set(&mut config.backtrace, rust.backtrace); |
| 1100 | + set(&mut config.channel, rust.channel); |
| 1101 | + config.description = rust.description; |
| 1102 | + set(&mut config.rust_dist_src, rust.dist_src); |
| 1103 | + set(&mut config.verbose_tests, rust.verbose_tests); |
| 1104 | + // in the case "false" is set explicitly, do not overwrite the command line args |
| 1105 | + if let Some(true) = rust.incremental { |
| 1106 | + config.incremental = true; |
| 1107 | + } |
| 1108 | + set(&mut config.use_lld, rust.use_lld); |
| 1109 | + set(&mut config.lld_enabled, rust.lld); |
| 1110 | + set(&mut config.llvm_tools_enabled, rust.llvm_tools); |
| 1111 | + config.rustc_parallel = rust.parallel_compiler.unwrap_or(false); |
| 1112 | + config.rustc_default_linker = rust.default_linker; |
| 1113 | + config.musl_root = rust.musl_root.map(PathBuf::from); |
| 1114 | + config.save_toolstates = rust.save_toolstates.map(PathBuf::from); |
| 1115 | + set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings)); |
| 1116 | + set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); |
| 1117 | + set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); |
| 1118 | + config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit; |
| 1119 | + set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo); |
| 1120 | + set(&mut config.control_flow_guard, rust.control_flow_guard); |
| 1121 | + config.llvm_libunwind_default = rust |
| 1122 | + .llvm_libunwind |
| 1123 | + .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); |
| 1124 | + |
| 1125 | + if let Some(ref backends) = rust.codegen_backends { |
| 1126 | + config.rust_codegen_backends = |
| 1127 | + backends.iter().map(|s| INTERNER.intern_str(s)).collect(); |
| 1128 | + } |
| 1129 | + |
| 1130 | + config.rust_codegen_units = rust.codegen_units.map(threads_from_config); |
| 1131 | + config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config); |
| 1132 | + config.rust_profile_use = flags.rust_profile_use.or(rust.profile_use); |
| 1133 | + config.rust_profile_generate = flags.rust_profile_generate.or(rust.profile_generate); |
| 1134 | + config.download_rustc_commit = config.download_ci_rustc_commit(rust.download_rustc); |
| 1135 | + |
| 1136 | + config.rust_lto = rust |
| 1137 | + .lto |
| 1138 | + .as_deref() |
| 1139 | + .map(|value| RustcLto::from_str(value).unwrap()) |
| 1140 | + .unwrap_or_default(); |
| 1141 | + } else { |
| 1142 | + config.rust_profile_use = flags.rust_profile_use; |
| 1143 | + config.rust_profile_generate = flags.rust_profile_generate; |
| 1144 | + } |
| 1145 | + |
1066 | 1146 | if let Some(llvm) = toml.llvm {
|
1067 | 1147 | match llvm.ccache {
|
1068 | 1148 | Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()),
|
@@ -1099,13 +1179,17 @@ impl Config {
|
1099 | 1179 | config.llvm_polly = llvm.polly.unwrap_or(false);
|
1100 | 1180 | config.llvm_clang = llvm.clang.unwrap_or(false);
|
1101 | 1181 | config.llvm_build_config = llvm.build_config.clone().unwrap_or(Default::default());
|
| 1182 | + |
| 1183 | + let asserts = llvm_assertions.unwrap_or(false); |
1102 | 1184 | config.llvm_from_ci = match llvm.download_ci_llvm {
|
1103 | 1185 | Some(StringOrBool::String(s)) => {
|
1104 | 1186 | assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s);
|
1105 |
| - crate::native::is_ci_llvm_available(&config, llvm_assertions.unwrap_or(false)) |
| 1187 | + crate::native::is_ci_llvm_available(&config, asserts) |
1106 | 1188 | }
|
1107 | 1189 | Some(StringOrBool::Bool(b)) => b,
|
1108 |
| - None => false, |
| 1190 | + None => { |
| 1191 | + config.channel == "dev" && crate::native::is_ci_llvm_available(&config, asserts) |
| 1192 | + } |
1109 | 1193 | };
|
1110 | 1194 |
|
1111 | 1195 | if config.llvm_from_ci {
|
@@ -1145,79 +1229,9 @@ impl Config {
|
1145 | 1229 | // the link step) with each stage.
|
1146 | 1230 | config.llvm_link_shared.set(Some(true));
|
1147 | 1231 | }
|
1148 |
| - } |
1149 |
| - |
1150 |
| - if let Some(rust) = toml.rust { |
1151 |
| - debug = rust.debug; |
1152 |
| - debug_assertions = rust.debug_assertions; |
1153 |
| - debug_assertions_std = rust.debug_assertions_std; |
1154 |
| - overflow_checks = rust.overflow_checks; |
1155 |
| - overflow_checks_std = rust.overflow_checks_std; |
1156 |
| - debug_logging = rust.debug_logging; |
1157 |
| - debuginfo_level = rust.debuginfo_level; |
1158 |
| - debuginfo_level_rustc = rust.debuginfo_level_rustc; |
1159 |
| - debuginfo_level_std = rust.debuginfo_level_std; |
1160 |
| - debuginfo_level_tools = rust.debuginfo_level_tools; |
1161 |
| - debuginfo_level_tests = rust.debuginfo_level_tests; |
1162 |
| - config.rust_split_debuginfo = rust |
1163 |
| - .split_debuginfo |
1164 |
| - .as_deref() |
1165 |
| - .map(SplitDebuginfo::from_str) |
1166 |
| - .map(|v| v.expect("invalid value for rust.split_debuginfo")) |
1167 |
| - .unwrap_or(SplitDebuginfo::default_for_platform(&config.build.triple)); |
1168 |
| - optimize = rust.optimize; |
1169 |
| - ignore_git = rust.ignore_git; |
1170 |
| - config.rust_new_symbol_mangling = rust.new_symbol_mangling; |
1171 |
| - set(&mut config.rust_optimize_tests, rust.optimize_tests); |
1172 |
| - set(&mut config.codegen_tests, rust.codegen_tests); |
1173 |
| - set(&mut config.rust_rpath, rust.rpath); |
1174 |
| - set(&mut config.jemalloc, rust.jemalloc); |
1175 |
| - set(&mut config.test_compare_mode, rust.test_compare_mode); |
1176 |
| - set(&mut config.backtrace, rust.backtrace); |
1177 |
| - set(&mut config.channel, rust.channel); |
1178 |
| - config.description = rust.description; |
1179 |
| - set(&mut config.rust_dist_src, rust.dist_src); |
1180 |
| - set(&mut config.verbose_tests, rust.verbose_tests); |
1181 |
| - // in the case "false" is set explicitly, do not overwrite the command line args |
1182 |
| - if let Some(true) = rust.incremental { |
1183 |
| - config.incremental = true; |
1184 |
| - } |
1185 |
| - set(&mut config.use_lld, rust.use_lld); |
1186 |
| - set(&mut config.lld_enabled, rust.lld); |
1187 |
| - set(&mut config.llvm_tools_enabled, rust.llvm_tools); |
1188 |
| - config.rustc_parallel = rust.parallel_compiler.unwrap_or(false); |
1189 |
| - config.rustc_default_linker = rust.default_linker; |
1190 |
| - config.musl_root = rust.musl_root.map(PathBuf::from); |
1191 |
| - config.save_toolstates = rust.save_toolstates.map(PathBuf::from); |
1192 |
| - set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings)); |
1193 |
| - set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); |
1194 |
| - set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); |
1195 |
| - config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit; |
1196 |
| - set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo); |
1197 |
| - set(&mut config.control_flow_guard, rust.control_flow_guard); |
1198 |
| - config.llvm_libunwind_default = rust |
1199 |
| - .llvm_libunwind |
1200 |
| - .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); |
1201 |
| - |
1202 |
| - if let Some(ref backends) = rust.codegen_backends { |
1203 |
| - config.rust_codegen_backends = |
1204 |
| - backends.iter().map(|s| INTERNER.intern_str(s)).collect(); |
1205 |
| - } |
1206 |
| - |
1207 |
| - config.rust_codegen_units = rust.codegen_units.map(threads_from_config); |
1208 |
| - config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config); |
1209 |
| - config.rust_profile_use = flags.rust_profile_use.or(rust.profile_use); |
1210 |
| - config.rust_profile_generate = flags.rust_profile_generate.or(rust.profile_generate); |
1211 |
| - config.download_rustc_commit = config.download_ci_rustc_commit(rust.download_rustc); |
1212 |
| - |
1213 |
| - config.rust_lto = rust |
1214 |
| - .lto |
1215 |
| - .as_deref() |
1216 |
| - .map(|value| RustcLto::from_str(value).unwrap()) |
1217 |
| - .unwrap_or_default(); |
1218 | 1232 | } else {
|
1219 |
| - config.rust_profile_use = flags.rust_profile_use; |
1220 |
| - config.rust_profile_generate = flags.rust_profile_generate; |
| 1233 | + config.llvm_from_ci = |
| 1234 | + config.channel == "dev" && crate::native::is_ci_llvm_available(&config, false); |
1221 | 1235 | }
|
1222 | 1236 |
|
1223 | 1237 | if let Some(t) = toml.target {
|
|
0 commit comments