Skip to content

Commit 1ce18d2

Browse files
authored
Rollup merge of #104512 - jyn514:download-ci-llvm-default, r=Mark-Simulacrum
Set `download-ci-llvm = "if-available"` by default when `channel = dev` See rust-lang/compiler-team#566. The motivation for changing the default is to avoid downloading and building LLVM when someone runs `x build` before running `x setup`. The motivation for only doing it on `channel = "dev"` is to avoid breaking distros or users installing from source. It works because `dev` is also the default channel. The diff looks larger than it is; most of it is moving the `llvm` branch below the `rust` so `config.channel` is set. r? `@Mark-Simulacrum` cc `@oli-obk` `@bjorn3` `@cuviper`
2 parents 0f5d3ba + ac67262 commit 1ce18d2

File tree

5 files changed

+141
-100
lines changed

5 files changed

+141
-100
lines changed

config.toml.example

+3-4
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,16 @@ changelog-seen = 2
3535
# Unless you're developing for a target where Rust CI doesn't build a compiler
3636
# toolchain or changing LLVM locally, you probably want to set this to true.
3737
#
38-
# This is false by default so that distributions don't unexpectedly download
39-
# LLVM from the internet.
40-
#
4138
# All tier 1 targets are currently supported; set this to `"if-available"` if
4239
# you are not sure whether you're on a tier 1 target.
4340
#
4441
# We also currently only support this when building LLVM for the build triple.
4542
#
4643
# Note that many of the LLVM options are not currently supported for
4744
# downloading. Currently only the "assertions" option can be toggled.
48-
#download-ci-llvm = false
45+
#
46+
# Defaults to "if-available" when `channel = "dev"` and "false" otherwise.
47+
#download-ci-llvm = "if-available"
4948

5049
# Indicates whether LLVM rebuild should be skipped when running bootstrap. If
5150
# this is `false` then the compiler's LLVM will be rebuilt whenever the built

src/bootstrap/config.rs

+108-94
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
//! This module implements parsing `config.toml` configuration files to tweak
44
//! how the build runs.
55
6+
#[cfg(test)]
7+
mod tests;
8+
69
use std::cell::{Cell, RefCell};
710
use std::cmp;
811
use std::collections::{HashMap, HashSet};
@@ -696,7 +699,7 @@ define_config! {
696699
}
697700
}
698701

699-
#[derive(Deserialize)]
702+
#[derive(Debug, Deserialize)]
700703
#[serde(untagged)]
701704
enum StringOrBool {
702705
String(String),
@@ -822,6 +825,29 @@ impl Config {
822825
}
823826

824827
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 {
825851
let flags = Flags::parse(&args);
826852
let mut config = Config::default_opts();
827853

@@ -907,25 +933,6 @@ impl Config {
907933

908934
config.stage0_metadata = t!(serde_json::from_slice::<Stage0Metadata>(&stage0_json));
909935

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-
929936
// Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory.
930937
let toml_path = flags
931938
.config
@@ -1063,6 +1070,79 @@ impl Config {
10631070
let mut optimize = None;
10641071
let mut ignore_git = None;
10651072

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+
10661146
if let Some(llvm) = toml.llvm {
10671147
match llvm.ccache {
10681148
Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()),
@@ -1099,13 +1179,17 @@ impl Config {
10991179
config.llvm_polly = llvm.polly.unwrap_or(false);
11001180
config.llvm_clang = llvm.clang.unwrap_or(false);
11011181
config.llvm_build_config = llvm.build_config.clone().unwrap_or(Default::default());
1182+
1183+
let asserts = llvm_assertions.unwrap_or(false);
11021184
config.llvm_from_ci = match llvm.download_ci_llvm {
11031185
Some(StringOrBool::String(s)) => {
11041186
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)
11061188
}
11071189
Some(StringOrBool::Bool(b)) => b,
1108-
None => false,
1190+
None => {
1191+
config.channel == "dev" && crate::native::is_ci_llvm_available(&config, asserts)
1192+
}
11091193
};
11101194

11111195
if config.llvm_from_ci {
@@ -1145,79 +1229,9 @@ impl Config {
11451229
// the link step) with each stage.
11461230
config.llvm_link_shared.set(Some(true));
11471231
}
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();
12181232
} 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);
12211235
}
12221236

12231237
if let Some(t) = toml.target {

src/bootstrap/config/tests.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use super::{Config, TomlConfig};
2+
use std::path::Path;
3+
4+
fn toml(config: &str) -> impl '_ + Fn(&Path) -> TomlConfig {
5+
|&_| toml::from_str(config).unwrap()
6+
}
7+
8+
fn parse(config: &str) -> Config {
9+
Config::parse_inner(&["check".to_owned(), "--config=/does/not/exist".to_owned()], toml(config))
10+
}
11+
12+
#[test]
13+
fn download_ci_llvm() {
14+
let parse_llvm = |s| parse(s).llvm_from_ci;
15+
let if_available = parse_llvm("llvm.download-ci-llvm = \"if-available\"");
16+
17+
assert!(parse_llvm("llvm.download-ci-llvm = true"));
18+
assert!(!parse_llvm("llvm.download-ci-llvm = false"));
19+
assert_eq!(parse_llvm(""), if_available);
20+
assert_eq!(parse_llvm("rust.channel = \"dev\""), if_available);
21+
assert!(!parse_llvm("rust.channel = \"stable\""));
22+
}
23+
24+
// FIXME: add test for detecting `src` and `out`

src/bootstrap/defaults/config.user.toml

+4
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ test-stage = 2
77
doc-stage = 2
88
# When compiling from source, you usually want all tools.
99
extended = true
10+
11+
[llvm]
12+
# Most users installing from source want to build all parts of the project from source, not just rustc itself.
13+
download-ci-llvm = false

src/bootstrap/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1639,10 +1639,10 @@ fn chmod(_path: &Path, _perms: u32) {}
16391639
/// If the test is running and code is an error code, it will cause a panic.
16401640
fn detail_exit(code: i32) -> ! {
16411641
// if in test and code is an error code, panic with status code provided
1642-
if cfg!(test) && code != 0 {
1642+
if cfg!(test) {
16431643
panic!("status code: {}", code);
16441644
} else {
1645-
//otherwise,exit with provided status code
1645+
// otherwise,exit with provided status code
16461646
std::process::exit(code);
16471647
}
16481648
}

0 commit comments

Comments
 (0)