Skip to content

Commit 8661e3e

Browse files
authored
replace dependencies with long build times when used together (closes #3571) (#3773)
1 parent dbc2873 commit 8661e3e

File tree

16 files changed

+475
-196
lines changed

16 files changed

+475
-196
lines changed

.changes/no-long-c-build-deps.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
"tauri": patch
3+
"tauri-codegen": patch
4+
"tauri-macros": patch
5+
"tauri-utils": patch
6+
---
7+
8+
Replace multiple dependencies who's C code compiled concurrently and caused
9+
the other ones to bloat compile time significantly.
10+
11+
* `zstd` -> `brotli`
12+
* `blake3` -> a vendored version of the blake3 reference
13+
* `ring` -> `getrandom`
14+
15+
See https://github.com/tauri-apps/tauri/pull/3773 for more information about
16+
these specific choices.

core/tauri-codegen/Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ readme = "README.md"
1515
[dependencies]
1616
sha2 = "0.10"
1717
base64 = "0.13"
18-
blake3 = { version = "1.3", features = [ "rayon" ] }
1918
proc-macro2 = "1"
2019
quote = "1"
2120
serde = { version = "1", features = [ "derive" ] }
2221
serde_json = "1"
2322
tauri-utils = { version = "1.0.0-rc.3", path = "../tauri-utils", features = [ "build" ] }
2423
thiserror = "1"
2524
walkdir = "2"
26-
zstd = { version = "0.11", optional = true }
25+
brotli = { version = "3", optional = true, default-features = false, features = ["std"] }
2726
regex = { version = "1.5.5", optional = true }
2827
uuid = { version = "0.8", features = [ "v4" ] }
2928

@@ -35,8 +34,7 @@ png = "0.17"
3534

3635
[features]
3736
default = [ "compression" ]
38-
compression = [ "zstd", "tauri-utils/compression" ]
37+
compression = [ "brotli", "tauri-utils/compression" ]
3938
isolation = [ "tauri-utils/isolation" ]
40-
__isolation-docs = [ "tauri-utils/__isolation-docs" ]
4139
shell-scope = [ "regex" ]
4240
config-json5 = [ "tauri-utils/config-json5" ]

core/tauri-codegen/src/context.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ fn load_csp(document: &mut NodeRef, key: &AssetKey, csp_hashes: &mut CspHashes)
5050
fn map_core_assets(
5151
options: &AssetOptions,
5252
) -> impl Fn(&AssetKey, &Path, &mut Vec<u8>, &mut CspHashes) -> Result<(), EmbeddedAssetsError> {
53-
#[cfg(any(feature = "isolation", feature = "__isolation-docs"))]
53+
#[cfg(feature = "isolation")]
5454
let pattern = tauri_utils::html::PatternObject::from(&options.pattern);
5555
let csp = options.csp;
5656
move |key, path, input, csp_hashes| {
@@ -60,7 +60,7 @@ fn map_core_assets(
6060
if csp {
6161
load_csp(&mut document, key, csp_hashes);
6262

63-
#[cfg(any(feature = "isolation", feature = "__isolation-docs"))]
63+
#[cfg(feature = "isolation")]
6464
if let tauri_utils::html::PatternObject::Isolation { .. } = &pattern {
6565
// create the csp for the isolation iframe styling now, to make the runtime less complex
6666
let mut hasher = Sha256::new();
@@ -78,7 +78,7 @@ fn map_core_assets(
7878
}
7979
}
8080

81-
#[cfg(any(feature = "isolation", feature = "__isolation-docs"))]
81+
#[cfg(feature = "isolation")]
8282
fn map_isolation(
8383
_options: &AssetOptions,
8484
dir: PathBuf,
@@ -284,7 +284,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
284284

285285
let pattern = match &options.pattern {
286286
PatternKind::Brownfield => quote!(#root::Pattern::Brownfield(std::marker::PhantomData)),
287-
#[cfg(any(feature = "isolation", feature = "__isolation-docs"))]
287+
#[cfg(feature = "isolation")]
288288
PatternKind::Isolation { dir } => {
289289
let dir = config_parent.join(dir);
290290
if !dir.exists() {

core/tauri-codegen/src/embedded_assets.rs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use quote::{quote, ToTokens, TokenStreamExt};
77
use sha2::{Digest, Sha256};
88
use std::{
99
collections::HashMap,
10+
fmt::Write,
1011
fs::File,
1112
path::{Path, PathBuf},
1213
};
@@ -15,12 +16,12 @@ use tauri_utils::config::PatternKind;
1516
use thiserror::Error;
1617
use walkdir::{DirEntry, WalkDir};
1718

19+
#[cfg(feature = "compression")]
20+
use brotli::enc::backward_references::BrotliEncoderParams;
21+
1822
/// The subdirectory inside the target directory we want to place assets.
1923
const TARGET_PATH: &str = "tauri-codegen-assets";
2024

21-
/// The minimum size needed for the hasher to use multiple threads.
22-
const MULTI_HASH_SIZE_LIMIT: usize = 131_072; // 128KiB
23-
2425
/// (key, (original filepath, compressed bytes))
2526
type Asset = (AssetKey, (PathBuf, PathBuf));
2627

@@ -40,6 +41,9 @@ pub enum EmbeddedAssetsError {
4041
error: std::io::Error,
4142
},
4243

44+
#[error("failed to create hex from bytes because {0}")]
45+
Hex(std::fmt::Error),
46+
4347
#[error("invalid prefix {prefix} used while including path {path}")]
4448
PrefixInvalid { prefix: PathBuf, path: PathBuf },
4549

@@ -182,7 +186,7 @@ pub struct AssetOptions {
182186
pub(crate) csp: bool,
183187
pub(crate) pattern: PatternKind,
184188
pub(crate) freeze_prototype: bool,
185-
#[cfg(any(feature = "isolation", feature = "__isolation-docs"))]
189+
#[cfg(feature = "isolation")]
186190
pub(crate) isolation_schema: String,
187191
}
188192

@@ -193,7 +197,7 @@ impl AssetOptions {
193197
csp: false,
194198
pattern,
195199
freeze_prototype: false,
196-
#[cfg(any(feature = "isolation", feature = "__isolation-docs"))]
200+
#[cfg(feature = "isolation")]
197201
isolation_schema: format!("isolation-{}", uuid::Uuid::new_v4()),
198202
}
199203
}
@@ -246,13 +250,19 @@ impl EmbeddedAssets {
246250

247251
/// Use highest compression level for release, the fastest one for everything else
248252
#[cfg(feature = "compression")]
249-
fn compression_level() -> i32 {
250-
let levels = zstd::compression_level_range();
253+
fn compression_settings() -> BrotliEncoderParams {
254+
let mut settings = BrotliEncoderParams::default();
255+
256+
// the following compression levels are hand-picked and are not min-maxed.
257+
// they have a good balance of runtime vs size for the respective profile goals.
258+
// see the "brotli" section of this comment https://github.com/tauri-apps/tauri/issues/3571#issuecomment-1054847558
251259
if cfg!(debug_assertions) {
252-
*levels.start()
260+
settings.quality = 2
253261
} else {
254-
*levels.end()
262+
settings.quality = 9
255263
}
264+
265+
settings
256266
}
257267

258268
/// Compress a file and spit out the information in a [`HashMap`] friendly form.
@@ -291,20 +301,24 @@ impl EmbeddedAssets {
291301

292302
// get a hash of the input - allows for caching existing files
293303
let hash = {
294-
let mut hasher = blake3::Hasher::new();
295-
if input.len() < MULTI_HASH_SIZE_LIMIT {
296-
hasher.update(&input);
297-
} else {
298-
hasher.update_rayon(&input);
304+
let mut hasher = crate::vendor::blake3_reference::Hasher::default();
305+
hasher.update(&input);
306+
307+
let mut bytes = [0u8; 32];
308+
hasher.finalize(&mut bytes);
309+
310+
let mut hex = String::with_capacity(2 * bytes.len());
311+
for b in bytes {
312+
write!(hex, "{:02x}", b).map_err(EmbeddedAssetsError::Hex)?;
299313
}
300-
hasher.finalize().to_hex()
314+
hex
301315
};
302316

303317
// use the content hash to determine filename, keep extensions that exist
304318
let out_path = if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
305319
out_dir.join(format!("{}.{}", hash, ext))
306320
} else {
307-
out_dir.join(hash.to_string())
321+
out_dir.join(hash)
308322
};
309323

310324
// only compress and write to the file if it doesn't already exist.
@@ -328,13 +342,16 @@ impl EmbeddedAssets {
328342
}
329343

330344
#[cfg(feature = "compression")]
331-
// entirely write input to the output file path with compression
332-
zstd::stream::copy_encode(&*input, out_file, Self::compression_level()).map_err(|error| {
333-
EmbeddedAssetsError::AssetWrite {
334-
path: path.to_owned(),
335-
error,
336-
}
337-
})?;
345+
{
346+
let mut input = std::io::Cursor::new(input);
347+
// entirely write input to the output file path with compression
348+
brotli::BrotliCompress(&mut input, &mut out_file, &Self::compression_settings()).map_err(
349+
|error| EmbeddedAssetsError::AssetWrite {
350+
path: path.to_owned(),
351+
error,
352+
},
353+
)?;
354+
}
338355
}
339356

340357
Ok((key, (path.into(), out_path)))

core/tauri-codegen/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub use tauri_utils::config::{parse::ConfigError, Config};
1111

1212
mod context;
1313
pub mod embedded_assets;
14+
#[doc(hidden)]
15+
pub mod vendor;
1416

1517
/// Represents all the errors that can happen while reading the config during codegen.
1618
#[derive(Debug, thiserror::Error)]

0 commit comments

Comments
 (0)