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