|
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