Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for create-exe syntax #3536

Merged
merged 17 commits into from
Feb 21, 2023
Merged
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions docs/dev/create-exe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# wasmer create-exe

## Motivation and Goal

The goal of create-exe is to create easily runnable executables on every
operating system.

In order to speed up the compilation process, the compilation and the create-exe
steps are split into three separate functions: `create-obj`, `create-exe` and `gen-c-header`.

By default, running `create-exe` is relatively simple:

```sh
wasmer create-exe myfile.wasm -o myfile.exe
./myfile.exe
```

When running `create-exe` on a wapm package that contains more than one .wasm file,
the resulting executable requires a `--command` or `-c` flag to select which module to start:

```sh
wasmer create-exe [email protected] -o wabt.exe
./wabt.exe
No --command given, available commands are:

wabt
wasm-interp
wasm-strip
wasm-validate
wasm2wat
wast2json
wat2wasm

./wabt.exe -c wasm2wat --version
1.0.37 (git~v1.0.37)
```

## create-obj

Some compilers have different advantages over other compilers, for example, the `-llvm`
compiler emits the best code, but is the slowest to compile, the `-singlepass` compiler
emits slow code, but is very fast to compile.

In order to cache compiled object and re-use them for recompilation, `wasmer create-obj`
exists to cache the output of the `wasm -> obj` compilation

```sh
# Requires wasmer >= 3.2.0-alpha.1
wasmer create-obj myfile.wasm-llvm -o myfile.o
ptitSeb marked this conversation as resolved.
Show resolved Hide resolved
# Run create-exe with the cached object file
wasmer create-exe myfile.wasm --precompiled-atom=myfile:myfile.o -o myfile.exe
```

The WebAssembly module (atom) name specified in the `--precompiled-atom` flag is the `.wasm` filename
without the extension or the module name in a multi-webassembly wapm package.

## Multi-command executables

When compiling multiple `.wasm` atoms into one executable, it could happen that
the function names generated by wasmer would clash with each other (ex.
`wasmer_function_1` from `object1.o` and `wasmer_function_1` from `object2.o`).

Therefore, wasmer inserts a prefix for these functions, which is apparent when running
`wasmer gen-c-header`:

```c
wasmer gen-c-header myfile.wasm -o myfile.h
cat myfile.h

// ...

// Compiled Wasm function pointers ordered by function index: the order they
// appeared in in the Wasm module.
extern void wasmer_function_6f62a6bc5c8f8e3e12a54e2ecbc5674ccfe1c75f91d8e4dd6ebb3fec422a4d6c_0(void);
extern void wasmer_function_6f62a6bc5c8f8e3e12a54e2ecbc5674ccfe1c75f91d8e4dd6ebb3fec422a4d6c_1(void);
extern void wasmer_function_6f62a6bc5c8f8e3e12a54e2ecbc5674ccfe1c75f91d8e4dd6ebb3fec422a4d6c_2(void);

// ...
```

By default, this "prefix" is the Sha256 hash of the input `.wasm` file and can be changed with the
`--prefix` flag on both `gen-c-header` and `create-obj`:

```c
wasmer gen-c-header myfile.wasm -o myfile.h --prefix abc123
cat myfile.h

// ...

// Compiled Wasm function pointers ordered by function index: the order they
// appeared in in the Wasm module.
extern void wasmer_function_abc123_0(void);
extern void wasmer_function_abc123_1(void);
extern void wasmer_function_abc123_2(void);

// ...
```

In order to instruct `create-exe` to use these object files, we can use the `--precompiled-atom` syntax
with `ATOM_NAME:PREFIX:PATH_TO_FILE` where `PREFIX` is optional and defaults to the Sha256 hash of the wasm file.

```sh
wasmer create-obj myfile.wasm -o myfile.o --prefix abc123
wasmer create-exe myfile.wasm -o myfile.exe --precompiled-atom myfile:abc123:myfile.o
```

The speedup is apparent when timing this command against the non-cached version:

```
time wasmer create-exe myfile.wasm -o myfile.exe
1,53s user 0,24s system 157% cpu 1,124 total
time wasmer create-exe myfile.wasm -o myfile.exe --precompiled-atom myfile:myfile.o
0,72s user 0,19s system 105% cpu 0,856 total
```