Skip to content

Commit 1ca802b

Browse files
committed
build: Tweak the organisation of the build config
The goal is enable us to add distro-toolchain specific compile time options trivially, whilst still having reasonably conservative onboarding defaults, such that users can successfully run `just get-started` on a variety of distributions. By setting os_release_id="(...)" in build.rs in boulder/ and moss/, we can now add specific flags known to work on platforms where we control the toolchain build-time options. As of now, the logic is working well enough that compilation doesn't stop working if you're not on Solus. The current solution is meant as starting point for a potentially more refined future solution if necessary. Tested on fedora 39 and Solus. Signed-off-by: Rune Morling <[email protected]>
1 parent fc70724 commit 1ca802b

File tree

7 files changed

+96
-23
lines changed

7 files changed

+96
-23
lines changed

.cargo/config.toml

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,42 @@
1-
[target."x86_64-unknown-linux-gnu"]
2-
# - On systems that do not use lld as the system linker (such as Solus) using lld directly saves about a second
3-
# of build time for incremental compiles for building boulder (from 2.191s to 1.198s on my machine).
4-
# - Compressing debug symbols with zstd shrinks the dev profile boulder binary from 206.03MB to 81.44MB, a 124.59MB
5-
# or ~60% savings. It doesn't affect the binary size for packaging builds since we strip those, but the debug symbols
6-
# are reduced in size from 113.16MB to 34.63MB. It adds about ~152ms to the build times which is less than we gained
7-
# by switching to lld
8-
# - The new symbol mangling format (https://doc.rust-lang.org/rustc/symbol-mangling/v0.html) improves the backtrace
9-
# shown by RUST_BACKTRACE=1 and other debug utilities. It should also be helpful once we have ABI reports. Upstream
10-
# hasn't switched to it yet by default due to stable distros not having new enough tools, but that doesn't matter for us
1+
# Having a way to detect on which system we are compiled means we can get
2+
# away with adding rustflags here that we know are present in the system
3+
# toolchain builds.
4+
#
5+
# We can set these extra flags via matching on a target cfg() expression.
6+
#
7+
# - On systems that do not use lld as the system linker (such as Solus) using
8+
# lld directly saves about a second of build time for incremental compiles
9+
# for building boulder (from 2.191s to 1.198s on Reilly's machine).
10+
#
11+
# - In testing, compression of debug symbols with zstd shrinks the dev profile
12+
# boulder binary from 206.03MB to 81.44MB, a 124.59MB or ~60% savings.
13+
# It doesn't affect the binary size for packaging builds since we strip those,
14+
# but the debug symbols are reduced in size from 113.16MB to 34.63MB.
15+
# It adds about ~152ms to the build times which is less than we gained by
16+
# switching to lld. This feature requires a compiler compiled with support
17+
# for zstd debug symbols.
18+
#
19+
# - The new symbol mangling format[1] improves the backtrace shown by
20+
# RUST_BACKTRACE=1 and other debug utilities. It should also be helpful once
21+
# we have ABI reports. Upstream hasn't switched to it yet by default due to
22+
# stable distros not having new enough tools, but that doesn't matter for us
23+
# [1]: https://doc.rust-lang.org/rustc/symbol-mangling/v0.html
24+
#
25+
26+
# NB: os_release patterns need to be added to both target configs for this to
27+
# work...
28+
#
29+
# The Solus toolchain supports zstd debug sections currently (Serpent doesn't)
30+
[target.'cfg(any(os_release_id = "solus"))']
1131
rustflags = [
1232
"-Clink-arg=-fuse-ld=lld",
1333
"-Clink-arg=-Wl,--compress-debug-sections=zstd",
1434
"-Csymbol-mangling-version=v0",
1535
]
1636

17-
[target."aarch64-unknown-linux-gnu"]
37+
# Default flags
38+
[target.'cfg(not(any(os_release_id = "solus")))']
1839
rustflags = [
1940
"-Clink-arg=-fuse-ld=lld",
20-
"-Clink-arg=-Wl,--compress-debug-sections=zstd",
2141
"-Csymbol-mangling-version=v0",
2242
]

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ diesel = { version = "2.2.1", features = ["sqlite", "returning_clauses_for_sqlit
2727
diesel_migrations = "2.2.0"
2828
dirs = "5.0.1"
2929
elf = "0.7.4"
30+
etc-os-release = "0.1.0"
3031
indicatif = "0.17.8"
3132
itertools = "0.13.0"
3233
futures = "0.3.30"
@@ -54,6 +55,19 @@ url = { version = "2.5.2", features = ["serde"] }
5455
xxhash-rust = { version = "0.8.11", features = ["xxh3"] }
5556
zstd = { version = "0.13.2", features = ["zstdmt"] }
5657

58+
# We want people who use the onboarding steps to get a nice compromise
59+
# between fast compilation and fast runtime, but with checks in place
60+
# and full backtraces. Hyperfine tests shows opt-level = 1 to be a good
61+
# compromise between compile speed and runtime speed.
62+
# During testing, opt-level = 2 caused a non-trivial slowdown in compilation
63+
# iteration speed, but also sped up execution times commensurably. /ermo
64+
[profile.onboarding]
65+
inherits = "dev"
66+
opt-level = 1
67+
lto = "thin"
68+
debug = true
69+
strip = "none"
70+
5771
[profile.release]
5872
lto = "thin"
5973

@@ -66,13 +80,4 @@ opt-level = 3
6680
strip = "none"
6781
debug = true
6882

69-
# We want people who use the onboarding steps to get a nice compromise
70-
# between fast compilation and fast runtime, but with checks in place
71-
# and full backtraces. Hyperfine tests shows opt-level = 1 to be a good
72-
# compromise between compile speed and runtime speed.
73-
[profile.onboarding]
74-
inherits = "dev"
75-
opt-level = 1
76-
lto = "thin"
77-
debug = true
78-
strip = "none"
83+
# NB: Consult .cargo/config.toml to read more about the conditional [target] rustflags we use!

boulder/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,6 @@ strum.workspace = true
4343
thiserror.workspace = true
4444
tokio.workspace = true
4545
url.workspace = true
46+
47+
[build-dependencies]
48+
etc-os-release.workspace = true

boulder/build.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use etc_os_release::OsRelease;
2+
use std::error::Error;
3+
4+
/// Set cargo::rustc-cfg=os_release_id="whatever" when /etc/os-release warrants it.
5+
/// The intent is to enable trivial conditional compilation via [target.'cfg(...)']
6+
/// stanzas.
7+
fn main() -> Result<(), Box<dyn Error>> {
8+
// only recompile when necessary
9+
println!("cargo::rerun-if-changed=./build.rs");
10+
// if /etc/os-release doesn't exist, we have a problem big enough that it's OK to crash
11+
let os_release = OsRelease::open()?;
12+
println!("cargo::rustc-cfg=os_release_id=\"{}\"", os_release.id());
13+
14+
Ok(())
15+
}

moss/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ clap.workspace = true
2121
derive_more.workspace = true
2222
diesel.workspace = true
2323
diesel_migrations.workspace = true
24-
itertools.workspace = true
2524
fnmatch = { path = "../crates/fnmatch" }
2625
futures.workspace = true
2726
hex.workspace = true
27+
itertools.workspace = true
2828
libsqlite3-sys.workspace = true
2929
log.workspace = true
3030
nix.workspace = true
@@ -39,6 +39,9 @@ thiserror.workspace = true
3939
url.workspace = true
4040
xxhash-rust.workspace = true
4141

42+
[build-dependencies]
43+
etc-os-release.workspace = true
44+
4245
[package.metadata.cargo-machete]
4346
# Needed for unixepoch() in src/db/state/migrations/2024-03-04-201550_init/up.sql
4447
ignored = ["libsqlite3-sys"]

moss/build.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use etc_os_release::OsRelease;
2+
use std::error::Error;
3+
4+
/// Set cargo::rustc-cfg=os_release_id="whatever" when /etc/os-release warrants it.
5+
/// The intent is to enable trivial conditional compilation via [target.'cfg(...)']
6+
/// stanzas.
7+
fn main() -> Result<(), Box<dyn Error>> {
8+
// only recompile when necessary
9+
println!("cargo::rerun-if-changed=./build.rs");
10+
// if /etc/os-release doesn't exist, we have a problem big enough that it's OK to crash
11+
let os_release = OsRelease::open()?;
12+
println!("cargo::rustc-cfg=os_release_id=\"{}\"", os_release.id());
13+
14+
Ok(())
15+
}

0 commit comments

Comments
 (0)