Add option to use LTO in release builds
Shrinks rslib.so from about 40MB to about 26MB, at the cost of considerably higher build time in a release build.
This commit is contained in:
parent
56a1046ff8
commit
c6f429ab17
|
@ -4,7 +4,7 @@ set -e
|
|||
|
||||
export PATH="$PATH:/state/rust/cargo/bin"
|
||||
export BUILD_ROOT=/state/build
|
||||
export RELEASE=1
|
||||
export RELEASE=2
|
||||
ln -sf out/node_modules .
|
||||
|
||||
if [ $(uname -m) = "aarch64" ]; then
|
||||
|
|
|
@ -152,3 +152,7 @@ debug = 0
|
|||
debug = 0
|
||||
[profile.dev.package.rsbridge]
|
||||
debug = 0
|
||||
|
||||
[profile.release-lto]
|
||||
inherits = "release"
|
||||
lto = true
|
||||
|
|
|
@ -8,6 +8,7 @@ use ninja_gen::archives::empty_manifest;
|
|||
use ninja_gen::archives::with_exe;
|
||||
use ninja_gen::archives::OnlineArchive;
|
||||
use ninja_gen::archives::Platform;
|
||||
use ninja_gen::build::BuildProfile;
|
||||
use ninja_gen::cargo::CargoBuild;
|
||||
use ninja_gen::cargo::RustOutput;
|
||||
use ninja_gen::git::SyncSubmodule;
|
||||
|
@ -269,7 +270,7 @@ fn build_pyoxidizer(build: &mut Build) -> Result<()> {
|
|||
"--manifest-path={} --target-dir={} -p pyoxidizer",
|
||||
"qt/bundle/PyOxidizer/Cargo.toml", "$builddir/bundle/rust"
|
||||
),
|
||||
release_override: Some(true),
|
||||
release_override: Some(BuildProfile::Release),
|
||||
},
|
||||
)?;
|
||||
Ok(())
|
||||
|
@ -320,7 +321,8 @@ impl BuildAction for BuildBundle {
|
|||
overriden_rust_target_triple()
|
||||
.unwrap_or_else(|| Platform::current().as_rust_triple()),
|
||||
),
|
||||
true,
|
||||
// our pyoxidizer bin uses lto on the release profile
|
||||
BuildProfile::Release,
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use ninja_gen::action::BuildAction;
|
||||
use ninja_gen::build::BuildProfile;
|
||||
use ninja_gen::build::FilesHandle;
|
||||
use ninja_gen::cargo::CargoBuild;
|
||||
use ninja_gen::cargo::CargoClippy;
|
||||
|
@ -202,7 +203,7 @@ pub fn check_minilints(build: &mut Build) -> Result<()> {
|
|||
outputs: &[RustOutput::Binary("minilints")],
|
||||
target: None,
|
||||
extra_args: "-p minilints",
|
||||
release_override: Some(false),
|
||||
release_override: Some(BuildProfile::Debug),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ use crate::input::BuildInput;
|
|||
pub struct Build {
|
||||
pub variables: HashMap<&'static str, String>,
|
||||
pub buildroot: Utf8PathBuf,
|
||||
pub release: bool,
|
||||
pub build_profile: BuildProfile,
|
||||
pub pools: Vec<(&'static str, usize)>,
|
||||
pub trailing_text: String,
|
||||
pub host_platform: Platform,
|
||||
|
@ -40,7 +40,7 @@ impl Build {
|
|||
|
||||
let mut build = Build {
|
||||
buildroot,
|
||||
release: std::env::var("RELEASE").is_ok(),
|
||||
build_profile: BuildProfile::from_env(),
|
||||
host_platform: Platform::current(),
|
||||
variables: Default::default(),
|
||||
pools: Default::default(),
|
||||
|
@ -102,7 +102,7 @@ impl Build {
|
|||
};
|
||||
|
||||
let mut statement =
|
||||
BuildStatement::from_build_action(group, action, &self.groups, self.release);
|
||||
BuildStatement::from_build_action(group, action, &self.groups, self.build_profile);
|
||||
|
||||
if first_invocation {
|
||||
let command = statement.prepare_command(command)?;
|
||||
|
@ -218,7 +218,7 @@ struct BuildStatement<'a> {
|
|||
env_vars: Vec<String>,
|
||||
working_dir: Option<String>,
|
||||
create_dirs: Vec<String>,
|
||||
release: bool,
|
||||
build_profile: BuildProfile,
|
||||
bypass_runner: bool,
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ impl BuildStatement<'_> {
|
|||
group: &str,
|
||||
mut action: impl BuildAction,
|
||||
existing_outputs: &'a HashMap<String, Vec<String>>,
|
||||
release: bool,
|
||||
build_profile: BuildProfile,
|
||||
) -> BuildStatement<'a> {
|
||||
let mut stmt = BuildStatement {
|
||||
existing_outputs,
|
||||
|
@ -244,7 +244,7 @@ impl BuildStatement<'_> {
|
|||
env_vars: Default::default(),
|
||||
working_dir: None,
|
||||
create_dirs: Default::default(),
|
||||
release,
|
||||
build_profile,
|
||||
bypass_runner: action.bypass_runner(),
|
||||
};
|
||||
action.files(&mut stmt);
|
||||
|
@ -328,6 +328,23 @@ fn expand_inputs(
|
|||
vec
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||
pub enum BuildProfile {
|
||||
Debug,
|
||||
Release,
|
||||
ReleaseWithLto,
|
||||
}
|
||||
|
||||
impl BuildProfile {
|
||||
fn from_env() -> Self {
|
||||
match std::env::var("RELEASE").unwrap_or_default().as_str() {
|
||||
"1" => Self::Release,
|
||||
"2" => Self::ReleaseWithLto,
|
||||
_ => Self::Debug,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FilesHandle {
|
||||
/// Add inputs to the build statement. Can be called multiple times with
|
||||
/// different variables. This is a shortcut for calling .expand_inputs()
|
||||
|
@ -391,7 +408,7 @@ pub trait FilesHandle {
|
|||
/// at the folder.
|
||||
fn create_dir_all(&mut self, key: &str, path: impl Into<String>);
|
||||
|
||||
fn release_build(&self) -> bool;
|
||||
fn build_profile(&self) -> BuildProfile;
|
||||
}
|
||||
|
||||
impl FilesHandle for BuildStatement<'_> {
|
||||
|
@ -474,8 +491,8 @@ impl FilesHandle for BuildStatement<'_> {
|
|||
expand_inputs(inputs, self.existing_outputs)
|
||||
}
|
||||
|
||||
fn release_build(&self) -> bool {
|
||||
self.release
|
||||
fn build_profile(&self) -> BuildProfile {
|
||||
self.build_profile
|
||||
}
|
||||
|
||||
fn add_output_stamp(&mut self, path: impl Into<String>) {
|
||||
|
|
|
@ -7,6 +7,7 @@ use camino::Utf8PathBuf;
|
|||
|
||||
use crate::action::BuildAction;
|
||||
use crate::archives::with_exe;
|
||||
use crate::build::BuildProfile;
|
||||
use crate::build::FilesHandle;
|
||||
use crate::input::BuildInput;
|
||||
use crate::inputs;
|
||||
|
@ -31,7 +32,12 @@ impl RustOutput<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn path(&self, rust_base: &Utf8Path, target: Option<&str>, release: bool) -> String {
|
||||
pub fn path(
|
||||
&self,
|
||||
rust_base: &Utf8Path,
|
||||
target: Option<&str>,
|
||||
build_profile: BuildProfile,
|
||||
) -> String {
|
||||
let filename = match *self {
|
||||
RustOutput::Binary(package) => {
|
||||
if cfg!(windows) {
|
||||
|
@ -56,20 +62,26 @@ impl RustOutput<'_> {
|
|||
if let Some(target) = target {
|
||||
path = path.join(target);
|
||||
}
|
||||
path = path
|
||||
.join(if release { "release" } else { "debug" })
|
||||
.join(filename);
|
||||
path = path.join(profile_output_dir(build_profile)).join(filename);
|
||||
path.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn profile_output_dir(profile: BuildProfile) -> &'static str {
|
||||
match profile {
|
||||
BuildProfile::Debug => "debug",
|
||||
BuildProfile::Release => "release",
|
||||
BuildProfile::ReleaseWithLto => "release-lto",
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct CargoBuild<'a> {
|
||||
pub inputs: BuildInput,
|
||||
pub outputs: &'a [RustOutput<'a>],
|
||||
pub target: Option<&'static str>,
|
||||
pub extra_args: &'a str,
|
||||
pub release_override: Option<bool>,
|
||||
pub release_override: Option<BuildProfile>,
|
||||
}
|
||||
|
||||
impl BuildAction for CargoBuild<'_> {
|
||||
|
@ -80,8 +92,8 @@ impl BuildAction for CargoBuild<'_> {
|
|||
fn files(&mut self, build: &mut impl FilesHandle) {
|
||||
let release_build = self
|
||||
.release_override
|
||||
.unwrap_or_else(|| build.release_build());
|
||||
let release_arg = if release_build { "--release" } else { "" };
|
||||
.unwrap_or_else(|| build.build_profile());
|
||||
let release_arg = profile_arg_for_cargo(release_build).unwrap_or_default();
|
||||
let target_arg = if let Some(target) = self.target {
|
||||
format!("--target {target}")
|
||||
} else {
|
||||
|
@ -114,6 +126,14 @@ impl BuildAction for CargoBuild<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
fn profile_arg_for_cargo(profile: BuildProfile) -> Option<&'static str> {
|
||||
match profile {
|
||||
BuildProfile::Debug => None,
|
||||
BuildProfile::Release => Some("--release"),
|
||||
BuildProfile::ReleaseWithLto => Some("--profile release-lto"),
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_flags(build: &mut Build) -> Result<()> {
|
||||
build.once_only("cargo_flags_and_pool", |build| {
|
||||
build.variable("cargo_flags", "--locked");
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
use anyhow::Result;
|
||||
|
||||
use crate::action::BuildAction;
|
||||
use crate::build::BuildProfile;
|
||||
use crate::build::FilesHandle;
|
||||
use crate::cargo::CargoBuild;
|
||||
use crate::cargo::RustOutput;
|
||||
|
@ -33,7 +34,7 @@ impl BuildAction for ConfigureBuild {
|
|||
outputs: &[RustOutput::Binary("configure")],
|
||||
target: None,
|
||||
extra_args: "-p configure",
|
||||
release_override: Some(false),
|
||||
release_override: Some(BuildProfile::Debug),
|
||||
},
|
||||
)?;
|
||||
Ok(())
|
||||
|
|
|
@ -105,7 +105,8 @@ To run Anki in optimized mode, use:
|
|||
./tools/runopt
|
||||
```
|
||||
|
||||
Or set RELEASE=1.
|
||||
Or set RELEASE=1 or RELEASE=2. The latter will further optimize the output, but make
|
||||
the build much slower.
|
||||
|
||||
## Building redistributable wheels
|
||||
|
||||
|
|
|
@ -55,3 +55,6 @@ build-mode-pyoxidizer-exe = []
|
|||
# to the directory containing build artifacts produced by `pyoxidizer`. If not
|
||||
# set, OUT_DIR will be used.
|
||||
build-mode-prebuilt-artifacts = []
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
Loading…
Reference in New Issue