wasm_opt/lib.rs
1//! Rust bindings to the `wasm-opt` WebAssembly optimizer.
2//!
3//! `wasm-opt` is a component of the [Binaryen] toolkit
4//! that optimizes [WebAssembly] modules. It is written
5//! in C++.
6//!
7//! [Binaryen]: https://github.com/WebAssembly/binaryen
8//! [WebAssembly]: https://webassembly.org/
9//!
10//! This project provides a Rust crate that builds `wasm-opt` and:
11//!
12//! 1) makes its command-line interface installable via `cargo install`,
13//! 2) provides an API to access it programmatically.
14//!
15//!
16//! ## Installing the binary
17//!
18//! ```text
19//! cargo install wasm-opt --locked
20//! ```
21//!
22//! It should behave exactly the same as `wasm-opt` installed from other sources.
23//!
24//!
25//! ## Using the library
26//!
27//! The crate provides an [`OptimizationOptions`] type that
28//! follows the builder pattern, with options that closely
29//! mirror the command line options of `wasm-opt`. Once built,
30//! call [`OptimizationOptions::run`] to load, optimize, and write
31//! the optimized module.
32//!
33//! ```no_run
34//! use wasm_opt::OptimizationOptions;
35//!
36//! let infile = "hello_world.wasm";
37//! let outfile = "hello_world_optimized.wasm";
38//!
39//! OptimizationOptions::new_optimize_for_size()
40//! .run(infile, outfile)?;
41//!
42//! # Ok::<(), anyhow::Error>(())
43//! ```
44//!
45//! There are constructors for all the typical optimization profiles:
46//!
47//! - [`OptimizationOptions::new_optimize_for_size`] · `-Os` or `-O`
48//! - [`OptimizationOptions::new_optimize_for_size_aggressively`] · `-Oz`
49//! - [`OptimizationOptions::new_opt_level_0`] · `-O0`, or no `-O*` argument.
50//! - [`OptimizationOptions::new_opt_level_1`] · `-O1`
51//! - [`OptimizationOptions::new_opt_level_2`] · `-O2`
52//! - [`OptimizationOptions::new_opt_level_3`] · `-O3`
53//! - [`OptimizationOptions::new_opt_level_4`] · `-O4`
54//!
55//! By default, the `run` method will read either binary `wasm` or text `wat` files,
56//! inspecting the first few bytes for the binary header and choosing as appropriate,
57//! and it will write a binary `wasm` file.
58//! This behavior can be changed with [`OptimizationOptions::reader_file_type`]
59//! and [`OptimizationOptions::writer_file_type`].
60//!
61//!
62//! ## Enabling and disabling WASM features
63//!
64//! The WebAssembly specification has [optional features](https://webassembly.org/roadmap/),
65//! represeted by the [`Feature`] enum.
66//! The `Feature` variants link to the relevant specifications of each feature when known.
67//! `wasm-opt` can be configured with support for them individually using the
68//! [`OptimizationOptions::enable_feature`] and [`OptimizationOptions::disable_feature`]
69//! methods.
70//!
71//! By default Binaryen (and this crate) enables these common features by default:
72//!
73//! - [`Feature::SignExt`]
74//! - [`Feature::MutableGlobals`].
75//!
76//! The original WebAssembly specification with no additional features is known
77//! as the _MVP_ specification. __To enable only the MVP features call
78//! [`OptimizationOptions::mvp_features_only`]__.
79//!
80//! After resetting to MVP features, additional calls to `enable_feature` will
81//! add features to the MVP feature set.
82//!
83//!
84//! ## Customizing passes
85//!
86//! All Binaryen optimization passes are represented in the [`Pass`]
87//! enum, and can be added to `OptimizationOptions` via [`OptimizationOptions::add_pass`].
88//! These are added after the default set of passes, which are
89//! enabled by most `OptimizationOptions` constructors. The default passes
90//! can be disabled either with the [`OptimizationOptions::new_opt_level_0`] constructor,
91//! or by calling [`OptimizationOptions::add_default_passes`]
92//! with a `false` argument.
93//!
94//! ```no_run
95//! use wasm_opt::{OptimizationOptions, Pass};
96//!
97//! let infile = "hello_world.wasm";
98//! let outfile = "hello_world_optimized.wasm";
99//!
100//! // Just run the inliner.
101//! OptimizationOptions::new_opt_level_0()
102//! .add_pass(Pass::InliningOptimizing)
103//! .run(infile, outfile)?;
104//!
105//! # Ok::<(), anyhow::Error>(())
106//! ```
107//!
108//! Note that while this crate exposes all Binaryen passes
109//! some may not make sense to actually use — Binaryen
110//! is a command-line oriented tool, and some passes are
111//! for debug purposes or print directly to the console.
112//!
113//!
114//! ## Integrating with existing tooling
115//!
116//! For ease of integration with tools that already use `wasm-opt` via CLI, this
117//! crate provides the [`integration`] module, which presents an API that is
118//! compatible with `std`s `Command`. This allows client code to use mostly the
119//! same code path for executing the `wasm-opt` CLI, and the crate-based API.
120//!
121//!
122//! ## Cargo features
123//!
124//! Enabled by default, the `dwarf` feature enables passes related to DWARF
125//! debug info. When enabled, this crate includes C++ code from the LLVM project.
126//! This can cause duplicate symbol linkage errors when _also_ linking to LLVM.
127//! When disabled, this code is not built, so can link successfully to LLVM,
128//! but the Binaryen DWARF passes will do nothing.
129
130// Most of the API surface is exported here.
131//
132// Many public methods are defined in other non-pub modules.
133pub use api::*;
134
135// Returned by the `run` method.
136pub use run::OptimizationError;
137
138// Easy integration with tools that already use `wasm-opt` via CLI.
139pub mod integration;
140
141// The "base" API.
142//
143// This API hides the `cxx` types,
144// but otherwise sticks closely to the Binaryen API.
145//
146// This is hidden because we don't need to commit to these low-level APIs,
147// but want to keep testing them from the `tests` folder.
148#[doc(hidden)]
149pub mod base;
150
151// Types and constructors used in the API.
152mod api;
153
154// A builder interface for `OptimizationOptions`.
155mod builder;
156
157// The list of optimization passes.
158mod passes;
159
160// Definitions of -O1, -O2, etc.
161mod profiles;
162
163// The list of wasm features.
164mod features;
165
166// The `run` method that re-implements the logic from `wasm-opt.cpp`
167// on top of `OptimizationOptions`.
168mod run;
169
170// A thin wrapper around `std::process::Command` that provides the unstable
171// `get_args` method.
172mod fake_command;