soroban_cli/commands/contract/
optimize.rs1use clap::{arg, command, Parser};
2use std::fmt::Debug;
3#[cfg(feature = "opt")]
4use wasm_opt::{Feature, OptimizationError, OptimizationOptions};
5
6use crate::wasm;
7
8#[derive(Parser, Debug, Clone)]
9#[group(skip)]
10pub struct Cmd {
11 #[command(flatten)]
12 wasm: wasm::Args,
13 #[arg(long)]
15 wasm_out: Option<std::path::PathBuf>,
16}
17
18#[derive(thiserror::Error, Debug)]
19pub enum Error {
20 #[error(transparent)]
21 Wasm(#[from] wasm::Error),
22 #[cfg(feature = "opt")]
23 #[error("optimization error: {0}")]
24 OptimizationError(OptimizationError),
25 #[cfg(not(feature = "opt"))]
26 #[error("Must install with \"opt\" feature, e.g. `cargo install --locked soroban-cli --features opt")]
27 Install,
28}
29
30impl Cmd {
31 #[cfg(not(feature = "opt"))]
32 pub fn run(&self) -> Result<(), Error> {
33 Err(Error::Install)
34 }
35
36 #[cfg(feature = "opt")]
37 pub fn run(&self) -> Result<(), Error> {
38 let wasm_size = self.wasm.len()?;
39
40 println!(
41 "Reading: {} ({} bytes)",
42 self.wasm.wasm.to_string_lossy(),
43 wasm_size
44 );
45
46 let wasm_out = self.wasm_out.as_ref().cloned().unwrap_or_else(|| {
47 let mut wasm_out = self.wasm.wasm.clone();
48 wasm_out.set_extension("optimized.wasm");
49 wasm_out
50 });
51
52 let mut options = OptimizationOptions::new_optimize_for_size_aggressively();
53 options.converge = true;
54
55 options.mvp_features_only();
63 options.enable_feature(Feature::MutableGlobals);
64 options.enable_feature(Feature::SignExt);
65
66 options
67 .run(&self.wasm.wasm, &wasm_out)
68 .map_err(Error::OptimizationError)?;
69
70 let wasm_out_size = wasm::len(&wasm_out)?;
71 println!(
72 "Optimized: {} ({} bytes)",
73 wasm_out.to_string_lossy(),
74 wasm_out_size
75 );
76
77 Ok(())
78 }
79}