Skip to content

Commit eb0f3dd

Browse files
authored
Rollup merge of rust-lang#76628 - jyn514:default-config-files, r=Mark-Simulacrum
Add sample defaults for config.toml - Allow including defaults in `src/bootstrap/defaults` using `profile = "..."`. - Add default config files, with a README noting they're experimental and asking you to open an issue if you run into trouble. The config files have comments explaining why the defaults are set. - Combine config files using the `merge` dependency. This introduces a new dependency on `merge` that hasn't yet been vetted. I want to improve the output when `include = "x"` isn't found: ``` thread 'main' panicked at 'fs::read_to_string(&file) failed with No such file or directory (os error 2) ("configuration file did not exist")', src/bootstrap/config.rs:522:28 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace failed to run: /home/joshua/rustc/build/bootstrap/debug/bootstrap test tidy Build completed unsuccessfully in 0:00:00 ``` However that seems like it could be fixed in a follow-up. Closes rust-lang#76619
2 parents be347bc + c9c8fb8 commit eb0f3dd

9 files changed

+136
-25
lines changed

Cargo.lock

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ dependencies = [
207207
"ignore",
208208
"lazy_static",
209209
"libc",
210+
"merge",
210211
"num_cpus",
211212
"opener",
212213
"pretty_assertions",
@@ -1909,6 +1910,28 @@ dependencies = [
19091910
"autocfg",
19101911
]
19111912

1913+
[[package]]
1914+
name = "merge"
1915+
version = "0.1.0"
1916+
source = "registry+https://github.com/rust-lang/crates.io-index"
1917+
checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
1918+
dependencies = [
1919+
"merge_derive",
1920+
"num-traits",
1921+
]
1922+
1923+
[[package]]
1924+
name = "merge_derive"
1925+
version = "0.1.0"
1926+
source = "registry+https://github.com/rust-lang/crates.io-index"
1927+
checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
1928+
dependencies = [
1929+
"proc-macro-error",
1930+
"proc-macro2",
1931+
"quote",
1932+
"syn",
1933+
]
1934+
19121935
[[package]]
19131936
name = "minifier"
19141937
version = "0.0.33"

config.toml.example

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99
# a custom configuration file can also be specified with `--config` to the build
1010
# system.
1111

12+
# =============================================================================
13+
# Global Settings
14+
# =============================================================================
15+
16+
# Use different pre-set defaults than the global defaults.
17+
#
18+
# See `src/bootstrap/defaults` for more information.
19+
# Note that this has no default value (x.py uses the defaults in `config.toml.example`).
20+
#profile = <none>
21+
1222
# =============================================================================
1323
# Tweaking how LLVM is compiled
1424
# =============================================================================

src/bootstrap/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ lazy_static = "1.3.0"
4949
time = "0.1"
5050
ignore = "0.4.10"
5151
opener = "0.4"
52+
merge = "0.1.0"
5253

5354
[target.'cfg(windows)'.dependencies.winapi]
5455
version = "0.3"

src/bootstrap/config.rs

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::flags::Flags;
1616
pub use crate::flags::Subcommand;
1717
use crate::util::exe;
1818
use build_helper::t;
19+
use merge::Merge;
1920
use serde::Deserialize;
2021

2122
macro_rules! check_ci_llvm {
@@ -278,10 +279,31 @@ struct TomlConfig {
278279
rust: Option<Rust>,
279280
target: Option<HashMap<String, TomlTarget>>,
280281
dist: Option<Dist>,
282+
profile: Option<String>,
283+
}
284+
285+
impl Merge for TomlConfig {
286+
fn merge(&mut self, TomlConfig { build, install, llvm, rust, dist, target, profile: _ }: Self) {
287+
fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>) {
288+
if let Some(new) = y {
289+
if let Some(original) = x {
290+
original.merge(new);
291+
} else {
292+
*x = Some(new);
293+
}
294+
}
295+
};
296+
do_merge(&mut self.build, build);
297+
do_merge(&mut self.install, install);
298+
do_merge(&mut self.llvm, llvm);
299+
do_merge(&mut self.rust, rust);
300+
do_merge(&mut self.dist, dist);
301+
assert!(target.is_none(), "merging target-specific config is not currently supported");
302+
}
281303
}
282304

283305
/// TOML representation of various global build decisions.
284-
#[derive(Deserialize, Default, Clone)]
306+
#[derive(Deserialize, Default, Clone, Merge)]
285307
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
286308
struct Build {
287309
build: Option<String>,
@@ -321,7 +343,7 @@ struct Build {
321343
}
322344

323345
/// TOML representation of various global install decisions.
324-
#[derive(Deserialize, Default, Clone)]
346+
#[derive(Deserialize, Default, Clone, Merge)]
325347
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
326348
struct Install {
327349
prefix: Option<String>,
@@ -338,7 +360,7 @@ struct Install {
338360
}
339361

340362
/// TOML representation of how the LLVM build is configured.
341-
#[derive(Deserialize, Default)]
363+
#[derive(Deserialize, Default, Merge)]
342364
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
343365
struct Llvm {
344366
skip_rebuild: Option<bool>,
@@ -365,7 +387,7 @@ struct Llvm {
365387
download_ci_llvm: Option<bool>,
366388
}
367389

368-
#[derive(Deserialize, Default, Clone)]
390+
#[derive(Deserialize, Default, Clone, Merge)]
369391
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
370392
struct Dist {
371393
sign_folder: Option<String>,
@@ -389,7 +411,7 @@ impl Default for StringOrBool {
389411
}
390412

391413
/// TOML representation of how the Rust build is configured.
392-
#[derive(Deserialize, Default)]
414+
#[derive(Deserialize, Default, Merge)]
393415
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
394416
struct Rust {
395417
optimize: Option<bool>,
@@ -434,7 +456,7 @@ struct Rust {
434456
}
435457

436458
/// TOML representation of how each build target is configured.
437-
#[derive(Deserialize, Default)]
459+
#[derive(Deserialize, Default, Merge)]
438460
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
439461
struct TomlTarget {
440462
cc: Option<String>,
@@ -524,27 +546,31 @@ impl Config {
524546
}
525547

526548
#[cfg(test)]
527-
let toml = TomlConfig::default();
549+
let get_toml = |_| TomlConfig::default();
528550
#[cfg(not(test))]
529-
let toml = flags
530-
.config
531-
.map(|file| {
532-
use std::process;
533-
534-
let contents = t!(fs::read_to_string(&file));
535-
match toml::from_str(&contents) {
536-
Ok(table) => table,
537-
Err(err) => {
538-
println!(
539-
"failed to parse TOML configuration '{}': {}",
540-
file.display(),
541-
err
542-
);
543-
process::exit(2);
544-
}
551+
let get_toml = |file: PathBuf| {
552+
use std::process;
553+
554+
let contents = t!(fs::read_to_string(&file), "configuration file did not exist");
555+
match toml::from_str(&contents) {
556+
Ok(table) => table,
557+
Err(err) => {
558+
println!("failed to parse TOML configuration '{}': {}", file.display(), err);
559+
process::exit(2);
545560
}
546-
})
547-
.unwrap_or_else(TomlConfig::default);
561+
}
562+
};
563+
564+
let mut toml = flags.config.map(get_toml).unwrap_or_else(TomlConfig::default);
565+
if let Some(include) = &toml.profile {
566+
let mut include_path = config.src.clone();
567+
include_path.push("src");
568+
include_path.push("bootstrap");
569+
include_path.push("defaults");
570+
include_path.push(format!("config.toml.{}", include));
571+
let included_toml = get_toml(include_path);
572+
toml.merge(included_toml);
573+
}
548574

549575
let build = toml.build.unwrap_or_default();
550576

src/bootstrap/defaults/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# About bootstrap defaults
2+
3+
These defaults are intended to be a good starting point for working with x.py,
4+
with the understanding that no one set of defaults make sense for everyone.
5+
6+
They are still experimental, and we'd appreciate your help improving them!
7+
If you use a setting that's not in these defaults that you think others would benefit from, please [file an issue] or make a PR with the changes.
8+
Similarly, if one of these defaults doesn't match what you use personally,
9+
please open an issue to get it changed.
10+
11+
[file an issue]: https://github.com/rust-lang/rust/issues/new/choose
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# These defaults are meant for contributors to the compiler who modify codegen or LLVM
2+
[llvm]
3+
# This enables debug-assertions in LLVM,
4+
# catching logic errors in codegen much earlier in the process.
5+
assertions = true
6+
7+
[rust]
8+
# This enables `RUSTC_LOG=debug`, avoiding confusing situations
9+
# where adding `debug!()` appears to do nothing.
10+
# However, it makes running the compiler slightly slower.
11+
debug-logging = true
12+
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
13+
incremental = true
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# These defaults are meant for contributors to the compiler who do not modify codegen or LLVM
2+
[rust]
3+
# This enables `RUSTC_LOG=debug`, avoiding confusing situations
4+
# where adding `debug!()` appears to do nothing.
5+
# However, it makes running the compiler slightly slower.
6+
debug-logging = true
7+
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
8+
incremental = true
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# These defaults are meant for contributors to the standard library and documentation.
2+
[build]
3+
# When building the standard library, you almost never want to build the compiler itself.
4+
build-stage = 0
5+
test-stage = 0
6+
bench-stage = 0
7+
8+
[rust]
9+
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
10+
incremental = true
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# These defaults are meant for users and distro maintainers building from source, without intending to make multiple changes.
2+
[build]
3+
# When compiling from source, you almost always want a full stage 2 build,
4+
# which has all the latest optimizations from nightly.
5+
build-stage = 2
6+
test-stage = 2
7+
doc-stage = 2
8+
# When compiling from source, you usually want all tools.
9+
extended = true

0 commit comments

Comments
 (0)