|
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