From 76b471ac7be707981164c02041fe4c546f4f4cc2 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 30 Aug 2024 13:24:51 +0200 Subject: [PATCH] WasmBuilder returns tuple with paths to wasm & opt wasm --- utils/wasm-builder/src/lib.rs | 22 ++++----- utils/wasm-builder/src/wasm_project.rs | 62 +++++++++++++------------- utils/wasm-optimizer/src/optimize.rs | 32 ++++++------- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 94fd5299c76..23ea71882ff 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -100,10 +100,12 @@ impl WasmBuilder { } /// Build the program and produce an output WASM binary. - pub fn build(self) -> Option { + /// + /// Returns tuple with paths to wasm & opt wasm file + pub fn build(self) -> Option<(PathBuf, PathBuf)> { if env::var("__GEAR_WASM_BUILDER_NO_BUILD").is_ok() || is_intellij_sync() { - let path = self.wasm_project.provide_dummy_wasm_binary_if_not_exist(); - return Some(path); + _ = self.wasm_project.provide_dummy_wasm_binary_if_not_exist(); + return None; } match self.build_project() { @@ -118,7 +120,7 @@ impl WasmBuilder { } } - fn build_project(mut self) -> Result> { + fn build_project(mut self) -> Result> { self.wasm_project.generate()?; self.cargo @@ -239,28 +241,28 @@ fn is_intellij_sync() -> bool { const FEATURES_TO_EXCLUDE_BY_DEFAULT: &[&str] = &["std"]; /// Shorthand function to be used in `build.rs`. -pub fn build() -> Option { +pub fn build() -> Option<(PathBuf, PathBuf)> { WasmBuilder::new() .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) .build() } /// Shorthand function to be used in `build.rs`. -pub fn build_with_metadata() -> Option { +pub fn build_with_metadata() -> Option<(PathBuf, PathBuf)> { WasmBuilder::with_meta(T::repr()) .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) .build() } /// Shorthand function to be used in `build.rs`. -pub fn build_metawasm() -> Option { +pub fn build_metawasm() -> Option<(PathBuf, PathBuf)> { WasmBuilder::new_metawasm() .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) .build() } /// Shorthand function to be used in `build.rs`. -pub fn recommended_nightly() -> Option { +pub fn recommended_nightly() -> Option<(PathBuf, PathBuf)> { WasmBuilder::new() .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) .with_recommended_toolchain() @@ -268,7 +270,7 @@ pub fn recommended_nightly() -> Option { } /// Shorthand function to be used in `build.rs`. -pub fn recommended_nightly_with_metadata() -> Option { +pub fn recommended_nightly_with_metadata() -> Option<(PathBuf, PathBuf)> { WasmBuilder::with_meta(T::repr()) .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) .with_recommended_toolchain() @@ -276,7 +278,7 @@ pub fn recommended_nightly_with_metadata() -> Option { } /// Shorthand function to be used in `build.rs`. -pub fn recommended_nightly_metawasm() -> Option { +pub fn recommended_nightly_metawasm() -> Option<(PathBuf, PathBuf)> { WasmBuilder::new_metawasm() .exclude_features(FEATURES_TO_EXCLUDE_BY_DEFAULT.to_vec()) .with_recommended_toolchain() diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index c9bbb8fa5a8..04f4859bb68 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . use crate::{code_validator::CodeValidator, crate_info::CrateInfo, smart_fs}; -use anyhow::{Context, Result}; +use anyhow::{Context, Ok, Result}; use chrono::offset::Local as ChronoLocal; use gear_wasm_optimizer::{self as optimize, OptType, Optimizer}; use gmeta::MetadataRepr; @@ -367,45 +367,40 @@ extern "C" fn metahash() {{ /// Generates output optimized wasm file, `.binpath` file for our tests /// system and wasm binaries informational file. /// Makes a copy of original wasm file in `self.wasm_target_dir`. - pub fn postprocess_opt( + pub fn postprocess_opt>( &self, - original_wasm_path: &PathBuf, + original_wasm_path: P, file_base_name: &String, - ) -> Result<()> { + ) -> Result { let [original_copy_wasm_path, opt_wasm_path] = [".wasm", ".opt.wasm"] .map(|ext| self.wasm_target_dir.join([file_base_name, ext].concat())); // Copy original file to `self.wasm_target_dir` - smart_fs::copy_if_newer(original_wasm_path, &original_copy_wasm_path) + smart_fs::copy_if_newer(&original_wasm_path, &original_copy_wasm_path) .context("unable to copy WASM file")?; // Optimize wasm using and `wasm-opt` and our optimizations. - if smart_fs::check_if_newer(original_wasm_path, &opt_wasm_path)? { - let path = optimize::optimize_wasm( - original_copy_wasm_path.clone(), - opt_wasm_path.clone(), - "4", - true, - ) - .map(|res| { - log::info!( - "Wasm-opt reduced wasm size: {} -> {}", - res.original_size, - res.optimized_size - ); - opt_wasm_path.clone() - }) - .unwrap_or_else(|err| { - println!("cargo:warning=wasm-opt optimizations error: {}", err); - original_copy_wasm_path.clone() - }); + if smart_fs::check_if_newer(&original_wasm_path, &opt_wasm_path)? { + let path = optimize::optimize_wasm(&original_copy_wasm_path, &opt_wasm_path, "4", true) + .map(|res| { + log::info!( + "Wasm-opt reduced wasm size: {} -> {}", + res.original_size, + res.optimized_size + ); + opt_wasm_path.clone() + }) + .unwrap_or_else(|err| { + println!("cargo:warning=wasm-opt optimizations error: {}", err); + original_copy_wasm_path.clone() + }); let mut optimizer = Optimizer::new(path)?; optimizer .insert_stack_end_export() .unwrap_or_else(|err| log::info!("Cannot insert stack end export: {}", err)); optimizer.strip_custom_sections(); - fs::write(opt_wasm_path.clone(), optimizer.optimize(OptType::Opt)?) + fs::write(&opt_wasm_path, optimizer.optimize(OptType::Opt)?) .context("Failed to write optimized WASM binary")?; } @@ -433,7 +428,8 @@ extern "C" fn metahash() {{ metadata, ), ) - .context("unable to write `wasm_binary.rs`") + .context("unable to write `wasm_binary.rs`")?; + Ok(opt_wasm_path) } /// Post-processing after the WASM binary has been built. @@ -442,7 +438,7 @@ extern "C" fn metahash() {{ /// `target/wasm32-unknown-unknown/` /// - Generate optimized and metadata WASM binaries from the built program /// - Generate `wasm_binary.rs` source file in `OUT_DIR` - pub fn postprocess(&self) -> Result> { + pub fn postprocess(&self) -> Result> { let file_base_name = self .file_base_name .as_ref() @@ -508,11 +504,14 @@ extern "C" fn metahash() {{ } } + // Tuple with PathBuf last wasm & opt.wasm + let mut wasm_paths: Option<(PathBuf, PathBuf)> = None; for (wasm_path, file_base_name) in &wasm_files { if self.project_type.is_metawasm() { self.postprocess_meta(wasm_path, file_base_name)?; } else { - self.postprocess_opt(wasm_path, file_base_name)?; + let wasm_opt = self.postprocess_opt(wasm_path, file_base_name)?; + wasm_paths = Some((wasm_path.clone(), wasm_opt)); } } @@ -530,8 +529,7 @@ extern "C" fn metahash() {{ if env::var("__GEAR_WASM_BUILDER_NO_FEATURES_TRACKING").is_err() { self.force_rerun_on_next_run(&original_wasm_path)?; } - - Ok(wasm_files.into_iter().map(|(path, _)| path).last()) + Ok(wasm_paths) } fn get_exports(file: &PathBuf) -> Result> { @@ -595,6 +593,6 @@ extern "C" fn metahash() {{ // Windows has path like `path\to\somewhere` which is incorrect for `include_*` // Rust's macros -fn display_path(path: &Path) -> String { - path.display().to_string().replace('\\', "/") +fn display_path>(path: P) -> String { + path.as_ref().display().to_string().replace('\\', "/") } diff --git a/utils/wasm-optimizer/src/optimize.rs b/utils/wasm-optimizer/src/optimize.rs index 8bcd3957876..aeef74992c3 100644 --- a/utils/wasm-optimizer/src/optimize.rs +++ b/utils/wasm-optimizer/src/optimize.rs @@ -28,9 +28,8 @@ use pwasm_utils::{ #[cfg(not(feature = "wasm-opt"))] use std::process::Command; use std::{ - ffi::OsStr, fs::{self, metadata}, - path::PathBuf, + path::{Path, PathBuf}, }; #[cfg(feature = "wasm-opt")] @@ -149,21 +148,22 @@ pub struct OptimizationResult { /// /// The intention is to reduce the size of bloated Wasm binaries as a result of /// missing optimizations (or bugs?) between Rust and Wasm. -pub fn optimize_wasm( - source: PathBuf, - destination: PathBuf, +pub fn optimize_wasm>( + source: P, + destination: P, optimization_passes: &str, keep_debug_symbols: bool, ) -> Result { let original_size = metadata(&source)?.len() as f64 / 1000.0; do_optimization( - source.as_os_str(), - destination.as_os_str(), + &source, + &destination, optimization_passes, keep_debug_symbols, )?; + let destination = destination.as_ref(); if !destination.exists() { return Err(anyhow::anyhow!( "Optimization failed, optimized wasm output file `{}` not found.", @@ -171,7 +171,7 @@ pub fn optimize_wasm( )); } - let optimized_size = metadata(&destination)?.len() as f64 / 1000.0; + let optimized_size = metadata(destination)?.len() as f64 / 1000.0; Ok(OptimizationResult { original_size, @@ -187,9 +187,9 @@ pub fn optimize_wasm( /// resulting in potentially a lot of time spent optimizing. /// /// If successful, the optimized Wasm is written to `dest_optimized`. -pub fn do_optimization( - dest_wasm: &OsStr, - dest_optimized: &OsStr, +pub fn do_optimization>( + dest_wasm: P, + dest_optimized: P, optimization_level: &str, keep_debug_symbols: bool, ) -> Result<()> { @@ -221,10 +221,10 @@ pub fn do_optimization( ); let mut command = Command::new(wasm_opt_path); command - .arg(dest_wasm) + .arg(dest_wasm.as_ref()) .arg(format!("-O{optimization_level}")) .arg("-o") - .arg(dest_optimized) + .arg(dest_optimized.as_ref()) .arg("-mvp") .arg("--enable-sign-ext") // the memory in our module is imported, `wasm-opt` needs to be told that @@ -259,9 +259,9 @@ pub fn do_optimization( /// resulting in potentially a lot of time spent optimizing. /// /// If successful, the optimized Wasm is written to `dest_optimized`. -pub fn do_optimization( - dest_wasm: &OsStr, - dest_optimized: &OsStr, +pub fn do_optimization>( + dest_wasm: P, + dest_optimized: P, optimization_level: &str, keep_debug_symbols: bool, ) -> Result<()> {