mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
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
9 changed files with 71 additions and 22 deletions
|
@ -4,7 +4,7 @@ set -e
|
||||||
|
|
||||||
export PATH="$PATH:/state/rust/cargo/bin"
|
export PATH="$PATH:/state/rust/cargo/bin"
|
||||||
export BUILD_ROOT=/state/build
|
export BUILD_ROOT=/state/build
|
||||||
export RELEASE=1
|
export RELEASE=2
|
||||||
ln -sf out/node_modules .
|
ln -sf out/node_modules .
|
||||||
|
|
||||||
if [ $(uname -m) = "aarch64" ]; then
|
if [ $(uname -m) = "aarch64" ]; then
|
||||||
|
|
|
@ -152,3 +152,7 @@ debug = 0
|
||||||
debug = 0
|
debug = 0
|
||||||
[profile.dev.package.rsbridge]
|
[profile.dev.package.rsbridge]
|
||||||
debug = 0
|
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::with_exe;
|
||||||
use ninja_gen::archives::OnlineArchive;
|
use ninja_gen::archives::OnlineArchive;
|
||||||
use ninja_gen::archives::Platform;
|
use ninja_gen::archives::Platform;
|
||||||
|
use ninja_gen::build::BuildProfile;
|
||||||
use ninja_gen::cargo::CargoBuild;
|
use ninja_gen::cargo::CargoBuild;
|
||||||
use ninja_gen::cargo::RustOutput;
|
use ninja_gen::cargo::RustOutput;
|
||||||
use ninja_gen::git::SyncSubmodule;
|
use ninja_gen::git::SyncSubmodule;
|
||||||
|
@ -269,7 +270,7 @@ fn build_pyoxidizer(build: &mut Build) -> Result<()> {
|
||||||
"--manifest-path={} --target-dir={} -p pyoxidizer",
|
"--manifest-path={} --target-dir={} -p pyoxidizer",
|
||||||
"qt/bundle/PyOxidizer/Cargo.toml", "$builddir/bundle/rust"
|
"qt/bundle/PyOxidizer/Cargo.toml", "$builddir/bundle/rust"
|
||||||
),
|
),
|
||||||
release_override: Some(true),
|
release_override: Some(BuildProfile::Release),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -320,7 +321,8 @@ impl BuildAction for BuildBundle {
|
||||||
overriden_rust_target_triple()
|
overriden_rust_target_triple()
|
||||||
.unwrap_or_else(|| Platform::current().as_rust_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 anyhow::Result;
|
||||||
use ninja_gen::action::BuildAction;
|
use ninja_gen::action::BuildAction;
|
||||||
|
use ninja_gen::build::BuildProfile;
|
||||||
use ninja_gen::build::FilesHandle;
|
use ninja_gen::build::FilesHandle;
|
||||||
use ninja_gen::cargo::CargoBuild;
|
use ninja_gen::cargo::CargoBuild;
|
||||||
use ninja_gen::cargo::CargoClippy;
|
use ninja_gen::cargo::CargoClippy;
|
||||||
|
@ -202,7 +203,7 @@ pub fn check_minilints(build: &mut Build) -> Result<()> {
|
||||||
outputs: &[RustOutput::Binary("minilints")],
|
outputs: &[RustOutput::Binary("minilints")],
|
||||||
target: None,
|
target: None,
|
||||||
extra_args: "-p minilints",
|
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 struct Build {
|
||||||
pub variables: HashMap<&'static str, String>,
|
pub variables: HashMap<&'static str, String>,
|
||||||
pub buildroot: Utf8PathBuf,
|
pub buildroot: Utf8PathBuf,
|
||||||
pub release: bool,
|
pub build_profile: BuildProfile,
|
||||||
pub pools: Vec<(&'static str, usize)>,
|
pub pools: Vec<(&'static str, usize)>,
|
||||||
pub trailing_text: String,
|
pub trailing_text: String,
|
||||||
pub host_platform: Platform,
|
pub host_platform: Platform,
|
||||||
|
@ -40,7 +40,7 @@ impl Build {
|
||||||
|
|
||||||
let mut build = Build {
|
let mut build = Build {
|
||||||
buildroot,
|
buildroot,
|
||||||
release: std::env::var("RELEASE").is_ok(),
|
build_profile: BuildProfile::from_env(),
|
||||||
host_platform: Platform::current(),
|
host_platform: Platform::current(),
|
||||||
variables: Default::default(),
|
variables: Default::default(),
|
||||||
pools: Default::default(),
|
pools: Default::default(),
|
||||||
|
@ -102,7 +102,7 @@ impl Build {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut statement =
|
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 {
|
if first_invocation {
|
||||||
let command = statement.prepare_command(command)?;
|
let command = statement.prepare_command(command)?;
|
||||||
|
@ -218,7 +218,7 @@ struct BuildStatement<'a> {
|
||||||
env_vars: Vec<String>,
|
env_vars: Vec<String>,
|
||||||
working_dir: Option<String>,
|
working_dir: Option<String>,
|
||||||
create_dirs: Vec<String>,
|
create_dirs: Vec<String>,
|
||||||
release: bool,
|
build_profile: BuildProfile,
|
||||||
bypass_runner: bool,
|
bypass_runner: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ impl BuildStatement<'_> {
|
||||||
group: &str,
|
group: &str,
|
||||||
mut action: impl BuildAction,
|
mut action: impl BuildAction,
|
||||||
existing_outputs: &'a HashMap<String, Vec<String>>,
|
existing_outputs: &'a HashMap<String, Vec<String>>,
|
||||||
release: bool,
|
build_profile: BuildProfile,
|
||||||
) -> BuildStatement<'a> {
|
) -> BuildStatement<'a> {
|
||||||
let mut stmt = BuildStatement {
|
let mut stmt = BuildStatement {
|
||||||
existing_outputs,
|
existing_outputs,
|
||||||
|
@ -244,7 +244,7 @@ impl BuildStatement<'_> {
|
||||||
env_vars: Default::default(),
|
env_vars: Default::default(),
|
||||||
working_dir: None,
|
working_dir: None,
|
||||||
create_dirs: Default::default(),
|
create_dirs: Default::default(),
|
||||||
release,
|
build_profile,
|
||||||
bypass_runner: action.bypass_runner(),
|
bypass_runner: action.bypass_runner(),
|
||||||
};
|
};
|
||||||
action.files(&mut stmt);
|
action.files(&mut stmt);
|
||||||
|
@ -328,6 +328,23 @@ fn expand_inputs(
|
||||||
vec
|
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 {
|
pub trait FilesHandle {
|
||||||
/// Add inputs to the build statement. Can be called multiple times with
|
/// Add inputs to the build statement. Can be called multiple times with
|
||||||
/// different variables. This is a shortcut for calling .expand_inputs()
|
/// different variables. This is a shortcut for calling .expand_inputs()
|
||||||
|
@ -391,7 +408,7 @@ pub trait FilesHandle {
|
||||||
/// at the folder.
|
/// at the folder.
|
||||||
fn create_dir_all(&mut self, key: &str, path: impl Into<String>);
|
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<'_> {
|
impl FilesHandle for BuildStatement<'_> {
|
||||||
|
@ -474,8 +491,8 @@ impl FilesHandle for BuildStatement<'_> {
|
||||||
expand_inputs(inputs, self.existing_outputs)
|
expand_inputs(inputs, self.existing_outputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn release_build(&self) -> bool {
|
fn build_profile(&self) -> BuildProfile {
|
||||||
self.release
|
self.build_profile
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_output_stamp(&mut self, path: impl Into<String>) {
|
fn add_output_stamp(&mut self, path: impl Into<String>) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ use camino::Utf8PathBuf;
|
||||||
|
|
||||||
use crate::action::BuildAction;
|
use crate::action::BuildAction;
|
||||||
use crate::archives::with_exe;
|
use crate::archives::with_exe;
|
||||||
|
use crate::build::BuildProfile;
|
||||||
use crate::build::FilesHandle;
|
use crate::build::FilesHandle;
|
||||||
use crate::input::BuildInput;
|
use crate::input::BuildInput;
|
||||||
use crate::inputs;
|
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 {
|
let filename = match *self {
|
||||||
RustOutput::Binary(package) => {
|
RustOutput::Binary(package) => {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
|
@ -56,20 +62,26 @@ impl RustOutput<'_> {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
path = path.join(target);
|
path = path.join(target);
|
||||||
}
|
}
|
||||||
path = path
|
path = path.join(profile_output_dir(build_profile)).join(filename);
|
||||||
.join(if release { "release" } else { "debug" })
|
|
||||||
.join(filename);
|
|
||||||
path.to_string()
|
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)]
|
#[derive(Debug, Default)]
|
||||||
pub struct CargoBuild<'a> {
|
pub struct CargoBuild<'a> {
|
||||||
pub inputs: BuildInput,
|
pub inputs: BuildInput,
|
||||||
pub outputs: &'a [RustOutput<'a>],
|
pub outputs: &'a [RustOutput<'a>],
|
||||||
pub target: Option<&'static str>,
|
pub target: Option<&'static str>,
|
||||||
pub extra_args: &'a str,
|
pub extra_args: &'a str,
|
||||||
pub release_override: Option<bool>,
|
pub release_override: Option<BuildProfile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuildAction for CargoBuild<'_> {
|
impl BuildAction for CargoBuild<'_> {
|
||||||
|
@ -80,8 +92,8 @@ impl BuildAction for CargoBuild<'_> {
|
||||||
fn files(&mut self, build: &mut impl FilesHandle) {
|
fn files(&mut self, build: &mut impl FilesHandle) {
|
||||||
let release_build = self
|
let release_build = self
|
||||||
.release_override
|
.release_override
|
||||||
.unwrap_or_else(|| build.release_build());
|
.unwrap_or_else(|| build.build_profile());
|
||||||
let release_arg = if release_build { "--release" } else { "" };
|
let release_arg = profile_arg_for_cargo(release_build).unwrap_or_default();
|
||||||
let target_arg = if let Some(target) = self.target {
|
let target_arg = if let Some(target) = self.target {
|
||||||
format!("--target {target}")
|
format!("--target {target}")
|
||||||
} else {
|
} 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<()> {
|
fn setup_flags(build: &mut Build) -> Result<()> {
|
||||||
build.once_only("cargo_flags_and_pool", |build| {
|
build.once_only("cargo_flags_and_pool", |build| {
|
||||||
build.variable("cargo_flags", "--locked");
|
build.variable("cargo_flags", "--locked");
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::action::BuildAction;
|
use crate::action::BuildAction;
|
||||||
|
use crate::build::BuildProfile;
|
||||||
use crate::build::FilesHandle;
|
use crate::build::FilesHandle;
|
||||||
use crate::cargo::CargoBuild;
|
use crate::cargo::CargoBuild;
|
||||||
use crate::cargo::RustOutput;
|
use crate::cargo::RustOutput;
|
||||||
|
@ -33,7 +34,7 @@ impl BuildAction for ConfigureBuild {
|
||||||
outputs: &[RustOutput::Binary("configure")],
|
outputs: &[RustOutput::Binary("configure")],
|
||||||
target: None,
|
target: None,
|
||||||
extra_args: "-p configure",
|
extra_args: "-p configure",
|
||||||
release_override: Some(false),
|
release_override: Some(BuildProfile::Debug),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -105,7 +105,8 @@ To run Anki in optimized mode, use:
|
||||||
./tools/runopt
|
./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
|
## Building redistributable wheels
|
||||||
|
|
||||||
|
|
|
@ -55,3 +55,6 @@ build-mode-pyoxidizer-exe = []
|
||||||
# to the directory containing build artifacts produced by `pyoxidizer`. If not
|
# to the directory containing build artifacts produced by `pyoxidizer`. If not
|
||||||
# set, OUT_DIR will be used.
|
# set, OUT_DIR will be used.
|
||||||
build-mode-prebuilt-artifacts = []
|
build-mode-prebuilt-artifacts = []
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
|
Loading…
Reference in a new issue