Skip to content

Commit f6c825d

Browse files
brsontakahser
andauthored
Add wasm-opt-for-rust proposal (#1070)
* Add wasm-opt-for-rust proposal * Clarify API deliverables * Update applications/wasm-opt-for-rust.md Co-authored-by: S E R A Y A <[email protected]> * Update applications/wasm-opt-for-rust.md Co-authored-by: S E R A Y A <[email protected]> * Fix ink! capitalization/punctuation Co-authored-by: S E R A Y A <[email protected]>
1 parent fcfcf5d commit f6c825d

File tree

1 file changed

+299
-0
lines changed

1 file changed

+299
-0
lines changed

applications/wasm-opt-for-rust.md

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
# W3F Grant Proposal
2+
3+
- **Project Name:** `wasm-opt` for Rust
4+
- **Team Name:** Common Orbit LLC
5+
- **Payment Address:** (Polkadot aUSD) 143W7CfR2R1dbATX3RVtrYfDXUMju1ua9pQh9B3DpLsuuB5M
6+
- **[Level](https://github.com/w3f/Grants-Program/tree/master#level_slider-levels):** 2
7+
8+
9+
10+
11+
## Project Overview :page_facing_up:
12+
13+
### Overview
14+
15+
This project makes the [`wasm-opt`] tool more accessible to Rust programmers.
16+
`wasm-opt` is a [WebAssembly] optimizer and is required by most software toolchains that
17+
produce WebAssembly binaries.
18+
19+
[`wasm-opt`]: https://rustwasm.github.io/book/reference/tools.html#wasm-opt--a-hrefhttpsgithubcomwebassemblybinaryenrepositorya
20+
[WebAssembly]: https://webassembly.org/
21+
22+
This project is to package `wasm-opt` as a cargo crate,
23+
so that it can be installed by typing
24+
25+
> `cargo install wasm-opt`
26+
27+
Additionally, it will provide a Rust API so that toolchain developers may,
28+
if they desire, call `wasm-opt` programmatically,
29+
so that their users are not required to manually install the tool.
30+
31+
`wasm-opt` is a part of the [binaryen] toolset, written in C++.
32+
It is almost universally required by all toolchains that compile to WebAssembly.
33+
It is required by Parity's [`cargo-contract`] tool for [ink!] development.
34+
35+
[binaryen]: https://github.com/WebAssembly/binaryen
36+
[`cargo-contract`]: https://github.com/paritytech/cargo-contract
37+
[ink!]: https://github.com/paritytech/ink
38+
39+
**This tool can not be aquired in the way Rust programmers expect &mdash; with `cargo install`.**
40+
Installation of the tool is system-dependent.
41+
Many system package managers have some version of it,
42+
in some cases an old version;
43+
or it can be downloaded in binary form for most platforms, from GitHub,
44+
in which case it has to be extracted and added to the environment `PATH` variable in an ad-hoc way.
45+
46+
In [our personal experience][wasmexp], aquiring this tool was a minor, but needless, barrier, to programming with [ink!].
47+
48+
[wasmexp]: #appendix-the-wasm-opt-installation-experience
49+
50+
In the course of this grant `cargo-contract` will receive pull requests
51+
to optionally enable both the following:
52+
53+
1) recommend installation via `cargo install wasm-opt`
54+
2) use `wasm-opt` via API and not require installation.
55+
56+
57+
58+
59+
### Project Details
60+
61+
Note that although `wasm-opt` comes from the binaryen suite of tools,
62+
this project is only focused on `wasm-opt`.
63+
All other binaryen tools are out of scope.
64+
If this project is successful and there is demand,
65+
future work can extend the technique to the rest of binaryen.
66+
67+
This project is technically straightforward.
68+
The main complication is that within `cargo` it is not possible to install binaries that were not produced
69+
directly by the Rust compiler.
70+
This means that it is not possible to simply build `wasm-opt` in a build script, then have `cargo` install it.
71+
72+
This is the basic approach we will take, for the executable:
73+
74+
- a `wasm-opt-sys` crate builds the C++ code for `wasm-opt`
75+
- the C++ source is built with only the C++ compiler all Rust users will have installed,
76+
no CMake or other build-system dependency
77+
- the C++ `wasm-opt` source is minimally-patched to export its `main` function with C ABI to be called from Rust
78+
- a `wasm-opt` crate contains a tiny Rust module that calls the C `wasm-opt` main function
79+
80+
We have prototyped the project sufficiently to believe the described approach will succeed.
81+
82+
For the library bindings:
83+
84+
- `wasm-opt-sys` will export low-level Rust bindings with the help of one
85+
of the common C++-integration crates, likely `cxx`
86+
- `wasm-opt` will provide an idiomatic Rust wrapper that exposes the necessary `wasm-opt` options programmatically
87+
88+
We will also deliver the following:
89+
90+
- Full README and API documentation
91+
- Basic regression tests for the binary and library
92+
- CI for the platforms
93+
- `aarch64-apple-darwin`
94+
- `aarch64-unknown-linux-gnu`
95+
- `i686-pc-windows-msvc`
96+
- `i686-unknown-linux-gnu`
97+
- `x86_64-apple-darwin`
98+
- `x86_64-pc-windows-msvc`
99+
- `x86_64-unknown-linux-gnu`
100+
- Pull requests adding optional support for the `wasm-opt` crate to
101+
- `cargo-contract`, the ink! build tool
102+
- One blog post about the tool and its development, at https://brson.github.io
103+
104+
105+
106+
107+
### Ecosystem Fit
108+
109+
This project is immediately useful to all Rust developers that build for wasm.
110+
111+
It is more specifically useful to developers of Rust-based toolchains that target wasm,
112+
and most specifically the `cargo-contract` tool used to compile ink! programs.
113+
It is probably relevant to authors of Substrate runtimes as well,
114+
though we do not have that experience yet.
115+
116+
117+
#### Prior Work and Alternatives
118+
119+
There are existing [Rust bindings for binaryen][brs].
120+
As-is they don't provide a route to installing `wasm-opt` via cargo.
121+
It is unclear if they provide the APIs needed to expose `wasm-opt` programmatically,
122+
though they probably do.
123+
These bindings appear to rely on CMake to build.
124+
We do not expect to use them directly, but may reference them during development.
125+
126+
[brs]: https://github.com/pepyakin/binaryen-rs
127+
128+
The [`cargo-wasi`] tool takes a [different strategy][cws] to acquiring `wasm-opt`.
129+
It automatically downloads the `wasm-opt` binary, presumably from the official releases.
130+
Other wasm toolchains like `cargo-contract` could follow a similar strategy,
131+
possibly by extracting the existing logic from `cargo-wasi`.
132+
133+
[`cargo-wasi`]: https://github.com/bytecodealliance/cargo-wasi
134+
[cws]: https://bytecodealliance.github.io/cargo-wasi/wasm-opt.html#which-wasm-opt-executed
135+
136+
137+
138+
139+
140+
## Team :busts_in_silhouette:
141+
142+
### Team members
143+
144+
- **Team lead:** [Brian Anderson](https://github.com/brson)
145+
- **Team member:** [Aimee Zhu](https://github.com/aimeedeer)
146+
147+
### Contact
148+
149+
- **Contact Name:** Brian Anderson
150+
- **Contact Email:** [email protected]
151+
- **Website:** https://brson.github.io
152+
153+
### Legal Structure
154+
155+
- **Registered Address:** 16192 Coastal Highway, Lewes, Delaware 19958
156+
- **Registered Legal Entity:** Common Orbit LLC
157+
158+
### Team's experience
159+
160+
The team lead is one of the original authors of the Rust programming language,
161+
with 12 years of Rust experience.
162+
They have performed Rust work for Mozilla, Reddit, PingCAP, Solana, MobileCoin, Parity, and Nervos.
163+
Both team members are maintainers of the [Rust in Blockchain](https://rustinblockchain.org/) newsletter.
164+
165+
### Team Code Repos
166+
167+
- https://github.com/brson/wasm-opt-rs
168+
- https://github.com/brson
169+
- https://github.com/aimeedeer
170+
171+
### Team LinkedIn Profiles (if available)
172+
173+
N/A
174+
175+
176+
177+
178+
## Development Status :open_book:
179+
180+
https://github.com/brson/wasm-opt-rs
181+
182+
We have created the initial project layout and investigated the feasibility of building the binaryen codebase using only the [`cc`] crate,
183+
as well as the feasibility of trivially calling the `wasm-opt` `main` function from Rust as described.
184+
185+
[`cc`]: https://docs.rs/cc/latest/cc/
186+
187+
We have reserved the `wasm-opt` and `wasm-opt-sys` crate names on crates.io.
188+
189+
190+
191+
192+
## Development Roadmap :nut_and_bolt:
193+
194+
### Overview
195+
196+
- **Total Estimated Duration:** 3-4 months
197+
- **Full-Time Equivalent (FTE):** 0.4
198+
- **Total Costs:** 30,000 USD
199+
200+
This will be a part time effort.
201+
I have divided this into two logical milestones,
202+
though in reality the work will overlap.
203+
204+
205+
### Milestone 1 — Proof of Concept
206+
207+
- **Estimated duration:** 1-2 month
208+
- **FTE:** 0.4
209+
- **Costs:** 15,000 USD
210+
211+
During this phase we will prove the concept and produce a `wasm-opt` Rust binary and API.
212+
213+
| Number | Deliverable | Specification |
214+
| -----: | ----------- | ------------- |
215+
| 0a. | License | MIT / Apache-2.0 |
216+
| 0b. | Documentation | Basic README. |
217+
| 0c. | Testing Guide | Manual smoke testing on Linux, Windows, and MacOS, x86_64 and ARM. |
218+
| 0d. | Docker | Docker is not required for this project. |
219+
| 1. | `wasm-opt` binary | Produce a `wasm-opt` binary that can be built by cargo but is otherwise identical to stock `wasm-opt`. |
220+
| 2. | APIs | Write an idiomatic, but possibly incomplete, Rust API for loading wasm, optimizing it, and writing it again. |
221+
222+
223+
### Milestone 2 — Integration
224+
225+
- **Estimated duration:** 1-2 month
226+
- **FTE:** 0.4
227+
- **Costs:** 15,000 USD
228+
229+
During this phase we will prepare the project for production and integrate it with `cargo-contract`.
230+
231+
| Number | Deliverable | Specification |
232+
| -----: | ----------- | ------------- |
233+
| 0a. | License | MIT / Apache-2.0 |
234+
| 0b. | Documentation | Full README and API docs. |
235+
| 0c. | Testing Guide | Basic integration tests for both binary and library. |
236+
| 0d. | Docker | Docker is not required for this project. |
237+
| 0e. | Article | Publish a technical blog post about how the project was developed and indicating it is available for use. |
238+
| 1. | APIs | Ensure the APIs expose all the `wasm-opt` options, and can be easily integrated into tools like `cargo-contract`. |
239+
| 2. | `cargo-contract` integration | Submit a PR to `cargo-contract` that integrates the `wasm-opt` crate. |
240+
| 3. | CI | Set up CI for all indicated platforms. |
241+
242+
243+
244+
245+
## Future Plans
246+
247+
Upon completion of this project we will pursue a maintainence grant
248+
to supply hourly funds for maintenance of this project.
249+
We expect maintenance to be minimal,
250+
primarily updating the code and making new releases to match upstream binaryen releases,
251+
and responding to issue reports.
252+
253+
We are interested in pursuing a pure-Rust alternative to `wasm-opt` with a limited
254+
focus of quickly shrinking wasm binaries.
255+
256+
We expect to pursue additional projects related to ink! and Substrate.
257+
258+
259+
260+
261+
## Appendix: The `wasm-opt` installation experience
262+
263+
Upon calling `cargo-contract build` without `wasm-opt` installed
264+
the build errors with this long explanation:
265+
266+
```
267+
ERROR: wasm-opt not found! Make sure the binary is in your PATH environment.
268+
269+
We use this tool to optimize the size of your contract's Wasm binary.
270+
271+
wasm-opt is part of the binaryen package. You can find detailed
272+
installation instructions on https://github.com/WebAssembly/binaryen#tools.
273+
274+
There are ready-to-install packages for many platforms:
275+
* Debian/Ubuntu: apt-get install binaryen
276+
* Homebrew: brew install binaryen
277+
* Arch Linux: pacman -S binaryen
278+
* Windows: binary releases at https://github.com/WebAssembly/binaryen/releases
279+
```
280+
281+
Despite the effort to explain how to install this tool,
282+
following the instructions on our system resulted in an old version of `wasm-opt`
283+
and `cargo-contract` produced a new error:
284+
285+
```
286+
ERROR: Your wasm-opt version is 91, but we require a version >= 99.
287+
288+
If you tried installing from your system package manager the best
289+
way forward is to download a recent binary release directly:
290+
291+
https://github.com/WebAssembly/binaryen/releases
292+
293+
Make sure that the `wasm-opt` file from that release is in your `PATH`.
294+
```
295+
296+
This actually did about the best that could be expected to help us
297+
get set up, and we did end up downloading the binary tarball,
298+
extracting it, and modifying our path.
299+
But the experience could be better.

0 commit comments

Comments
 (0)