From f76e961f89ac004a9fb9cd270c535947a29fd047 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 5 Nov 2018 10:50:24 -0500 Subject: [PATCH] build-sys: Turn Rust LTO off by default, add --enable-lto flag For us, this is primarily right now a size issue. See: https://internals.rust-lang.org/t/rust-staticlibs-and-optimizing-for-size/5746 For more information, there are these two issues: https://github.com/rust-lang/cargo/issues/4349 https://bugzilla.mozilla.org/show_bug.cgi?id=1386371 The basic issue here is that a build with LTO off (and a trivial change to add a `println!` takes 14s here, and with it on takes 38s. However, with LTO off the stripped size of `librpmostree_rust.a` is `6M`, with LTO on it's `1.1M`. I named this `--enable-lto` as I'd like to investigate doing this for the C code too. --- configure.ac | 17 +++++++++++++++-- rust/Cargo.toml | 8 +++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 6357ef1bab..ef2ab0a7f4 100644 --- a/configure.ac +++ b/configure.ac @@ -228,7 +228,7 @@ fi AC_MSG_RESULT($debug_release) dnl These bits based on gnome:librsvg/configure.ac -dnl By default, we build in public release mode. +dnl By default, we build in release mode (but without LTO!) AC_ARG_ENABLE(rust-debug, AC_HELP_STRING([--enable-rust-debug], [Build Rust code with debugging information [default=no]]), @@ -244,6 +244,19 @@ AM_CONDITIONAL(RUST_DEBUG, [test "x$rust_debug_release" = "xdebug"]) dnl Unconditional now. RPM_OSTREE_FEATURES="$RPM_OSTREE_FEATURES rust" +dnl Only use this for package builds, as it will hackily edit Cargo.toml right now +AC_ARG_ENABLE(lto, +AC_HELP_STRING([--enable-lto], + [Build code with Link Time Optimization [default=no]])) +dnl https://github.com/rust-lang/cargo/issues/4349 +dnl https://bugzilla.mozilla.org/show_bug.cgi?id=1386371 +if test "${enable_lto}" = yes; then + if ! grep -q '^lto.*=true' rust/Cargo.toml 2>/dev/null; then + echo '# Inserted by configure --enable-lto' >> rust/Cargo.toml + echo "lto = true" >> rust/Cargo.toml + fi +fi + dnl And propagate the release/debug type to cmake cmake_args=-DCMAKE_BUILD_TYPE=RelWithDebugInfo if test ${debug_release} = debug; then @@ -286,6 +299,6 @@ echo " introspection: $found_introspection bubblewrap: $with_bubblewrap gtk-doc: $enable_gtk_doc - rust: $rust_debug_release + rust: $rust_debug_release (lto: ${enable_lto:-no}) cbindgen: ${cbindgen:-internal} " diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 62aa51a464..1e7b1be92e 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -24,6 +24,12 @@ path = "src/lib.rs" crate-type = ["staticlib"] [profile.release] +# Unwinding across FFI boundaries is undefined behavior, and anyways, we're +# [crash-only](https://en.wikipedia.org/wiki/Crash-only_software) panic = "abort" -lto = true +# We assume we're being delivered via e.g. RPM which supports split debuginfo debug = true +# For true release builds, we do suggest you enable LTO via e.g. +# env RUSTFLAGS='-C lto=true' as part of the outer build. It's just +# off by default because it's quite slow and the default is more oriented +# towards local development.