Skip to content

Commit

Permalink
build: Tweak the organisation of the build config
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
ermo committed Jul 18, 2024
1 parent fc70724 commit 1ca802b
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 23 deletions.
44 changes: 32 additions & 12 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
[target."x86_64-unknown-linux-gnu"]
# - On systems that do not use lld as the system linker (such as Solus) using lld directly saves about a second
# of build time for incremental compiles for building boulder (from 2.191s to 1.198s on my machine).
# - Compressing debug symbols with zstd shrinks the dev profile boulder binary from 206.03MB to 81.44MB, a 124.59MB
# or ~60% savings. It doesn't affect the binary size for packaging builds since we strip those, but the debug symbols
# are reduced in size from 113.16MB to 34.63MB. It adds about ~152ms to the build times which is less than we gained
# by switching to lld
# - The new symbol mangling format (https://doc.rust-lang.org/rustc/symbol-mangling/v0.html) improves the backtrace
# shown by RUST_BACKTRACE=1 and other debug utilities. It should also be helpful once we have ABI reports. Upstream
# hasn't switched to it yet by default due to stable distros not having new enough tools, but that doesn't matter for us
# Having a way to detect on which system we are compiled means we can get
# away with adding rustflags here that we know are present in the system
# toolchain builds.
#
# We can set these extra flags via matching on a target cfg() expression.
#
# - On systems that do not use lld as the system linker (such as Solus) using
# lld directly saves about a second of build time for incremental compiles
# for building boulder (from 2.191s to 1.198s on Reilly's machine).
#
# - In testing, compression of debug symbols with zstd shrinks the dev profile
# boulder binary from 206.03MB to 81.44MB, a 124.59MB or ~60% savings.
# It doesn't affect the binary size for packaging builds since we strip those,
# but the debug symbols are reduced in size from 113.16MB to 34.63MB.
# It adds about ~152ms to the build times which is less than we gained by
# switching to lld. This feature requires a compiler compiled with support
# for zstd debug symbols.
#
# - The new symbol mangling format[1] improves the backtrace shown by
# RUST_BACKTRACE=1 and other debug utilities. It should also be helpful once
# we have ABI reports. Upstream 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]: https://doc.rust-lang.org/rustc/symbol-mangling/v0.html
#

# NB: os_release patterns need to be added to both target configs for this to
# work...
#
# The Solus toolchain supports zstd debug sections currently (Serpent doesn't)
[target.'cfg(any(os_release_id = "solus"))']
rustflags = [
"-Clink-arg=-fuse-ld=lld",
"-Clink-arg=-Wl,--compress-debug-sections=zstd",
"-Csymbol-mangling-version=v0",
]

[target."aarch64-unknown-linux-gnu"]
# Default flags
[target.'cfg(not(any(os_release_id = "solus")))']
rustflags = [
"-Clink-arg=-fuse-ld=lld",
"-Clink-arg=-Wl,--compress-debug-sections=zstd",
"-Csymbol-mangling-version=v0",
]
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 15 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ diesel = { version = "2.2.1", features = ["sqlite", "returning_clauses_for_sqlit
diesel_migrations = "2.2.0"
dirs = "5.0.1"
elf = "0.7.4"
etc-os-release = "0.1.0"
indicatif = "0.17.8"
itertools = "0.13.0"
futures = "0.3.30"
Expand Down Expand Up @@ -54,6 +55,19 @@ url = { version = "2.5.2", features = ["serde"] }
xxhash-rust = { version = "0.8.11", features = ["xxh3"] }
zstd = { version = "0.13.2", features = ["zstdmt"] }

# We want people who use the onboarding steps to get a nice compromise
# between fast compilation and fast runtime, but with checks in place
# and full backtraces. Hyperfine tests shows opt-level = 1 to be a good
# compromise between compile speed and runtime speed.
# During testing, opt-level = 2 caused a non-trivial slowdown in compilation
# iteration speed, but also sped up execution times commensurably. /ermo
[profile.onboarding]
inherits = "dev"
opt-level = 1
lto = "thin"
debug = true
strip = "none"

[profile.release]
lto = "thin"

Expand All @@ -66,13 +80,4 @@ opt-level = 3
strip = "none"
debug = true

# We want people who use the onboarding steps to get a nice compromise
# between fast compilation and fast runtime, but with checks in place
# and full backtraces. Hyperfine tests shows opt-level = 1 to be a good
# compromise between compile speed and runtime speed.
[profile.onboarding]
inherits = "dev"
opt-level = 1
lto = "thin"
debug = true
strip = "none"
# NB: Consult .cargo/config.toml to read more about the conditional [target] rustflags we use!
3 changes: 3 additions & 0 deletions boulder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ strum.workspace = true
thiserror.workspace = true
tokio.workspace = true
url.workspace = true

[build-dependencies]
etc-os-release.workspace = true
15 changes: 15 additions & 0 deletions boulder/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use etc_os_release::OsRelease;
use std::error::Error;

/// Set cargo::rustc-cfg=os_release_id="whatever" when /etc/os-release warrants it.
/// The intent is to enable trivial conditional compilation via [target.'cfg(...)']
/// stanzas.
fn main() -> Result<(), Box<dyn Error>> {
// only recompile when necessary
println!("cargo::rerun-if-changed=./build.rs");
// if /etc/os-release doesn't exist, we have a problem big enough that it's OK to crash
let os_release = OsRelease::open()?;
println!("cargo::rustc-cfg=os_release_id=\"{}\"", os_release.id());

Ok(())
}
5 changes: 4 additions & 1 deletion moss/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ clap.workspace = true
derive_more.workspace = true
diesel.workspace = true
diesel_migrations.workspace = true
itertools.workspace = true
fnmatch = { path = "../crates/fnmatch" }
futures.workspace = true
hex.workspace = true
itertools.workspace = true
libsqlite3-sys.workspace = true
log.workspace = true
nix.workspace = true
Expand All @@ -39,6 +39,9 @@ thiserror.workspace = true
url.workspace = true
xxhash-rust.workspace = true

[build-dependencies]
etc-os-release.workspace = true

[package.metadata.cargo-machete]
# Needed for unixepoch() in src/db/state/migrations/2024-03-04-201550_init/up.sql
ignored = ["libsqlite3-sys"]
15 changes: 15 additions & 0 deletions moss/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use etc_os_release::OsRelease;
use std::error::Error;

/// Set cargo::rustc-cfg=os_release_id="whatever" when /etc/os-release warrants it.
/// The intent is to enable trivial conditional compilation via [target.'cfg(...)']
/// stanzas.
fn main() -> Result<(), Box<dyn Error>> {
// only recompile when necessary
println!("cargo::rerun-if-changed=./build.rs");
// if /etc/os-release doesn't exist, we have a problem big enough that it's OK to crash
let os_release = OsRelease::open()?;
println!("cargo::rustc-cfg=os_release_id=\"{}\"", os_release.id());

Ok(())
}

0 comments on commit 1ca802b

Please sign in to comment.