Skip to content

Commit

Permalink
Added more documentation about how to load the WebAssembly within a w…
Browse files Browse the repository at this point in the history
…eb page
  • Loading branch information
srydell committed Mar 10, 2022
1 parent 3034ae3 commit efa5f27
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.15)
project(
Frontend.wasm
VERSION 0.4.2
VERSION 0.4.3
LANGUAGES CXX)

configure_file(docs/ReleaseNotes/version.in
Expand Down
5 changes: 5 additions & 0 deletions docs/ReleaseNotes/v0.4.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# News #

## Documentation ##

* More documentation about how to serve the `WebAssembly` with a web server
59 changes: 57 additions & 2 deletions docs/public/introduction.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# WebAssembly with Tolc #

In order for `C++` to be called from `javascript` there has to be an interface level. `tolc` generates this level from your already written `C++` interface.
To be as close to what an engineer would have written, `tolc` generates human readable [`embind11`](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#embind).
To be as close to what an engineer would have written, `tolc` generates human readable [`embind`](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#embind).
This is then compiled to a `.wasm` and a `.js` file that `javascript` can import.

## Using a `C++` library from `javascript` ##
Expand Down Expand Up @@ -81,7 +81,8 @@ $ emsdk.bat activate 3.1.3

### Configuring Your Project ###

Now when configuring your `CMake` project, pass the toolchain flag `-DCMAKE_TOOLCHAIN_FILE=${EMSDK_DIRECTORY}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake`. Where you need to replace `${EMSDK_DIRECTORY}` with the directory of the previously downloaded `Emscripten SDK`. Note that the directory separator used by `CMake` is always forward slash (`/`), even on Windows.
Since `CMake` doesn't have native support for `WebAssembly` we have to provide a `toolchain` file, fortunately for us, `Emscripten` provides us with one.
When configuring your `CMake` project, just pass the toolchain flag `-DCMAKE_TOOLCHAIN_FILE=${EMSDK_DIRECTORY}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake`. Where you need to replace `${EMSDK_DIRECTORY}` with the directory of the previously downloaded `Emscripten SDK`. Note that the directory separator used by `CMake` is always forward slash (`/`), even on Windows.

Example:

Expand All @@ -90,6 +91,7 @@ Example:
$ cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=${EMSDK_DIRECTORY}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
```


### Using From `javascript` ###

Looking into `build/tolc` you should see `MyLib.js` aswell as `MyLib.wasm`. `MyLib.js` exports a `Promise` that loads the built `WebAssembly`. Here is an example usage:
Expand All @@ -104,5 +106,58 @@ loadMyLib().then(MyLib => {
});
```

Running the file as normal:

```shell
$ node run.js
```


### Using from a web page ###

By default `Emscripten` assumes that you're running your code in a `node` environment (e.g. having access to the filesystem).
This is not the case on a web page served to a browser. If we add the link flag `-s ENVIRONMENT='web'` to `Emscripten` it will produce a serveable `WebAssembly` module.
Since `Tolc` exposes a `CMake` build target for the module, all we have to do is add the flag ourself:

```cmake
# Creates the CMake target ${TARGET}_${LANGUAGE}
# In this case: MyLib_wasm
tolc_create_bindings(
TARGET MyLib
LANGUAGE wasm
OUTPUT wasm-bindings
)
# Want to deploy to a web page
set_property(
TARGET MyLib_wasm
APPEND_STRING
PROPERTY LINK_FLAGS "-s ENVIRONMENT='web'")
```

Then we copy over `MyLib.js` and `MyLib.wasm` to our web application and load them as shown previously:

```javascript
// app.js
const loadMyLib = require('./MyLib');

loadMyLib().then(MyLib => {
// From here you can use the C++ functions of your library as usual
MyLib.myCppFunction();
});
```

Assuming you've loaded the `javascript` within your page:

```html
<!-- index.html -->
...
<head>
<script type="text/javascript" src="./app.js"></script>
</head>
...
```


If you want to see what more is supported you can take a look at [the Examples section](./examples.md).

2 changes: 1 addition & 1 deletion tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ When the `stage` runs its destructor, the `stage` directory is removed. This can

### EmbindStage ###

The `TestUtil` library provides `EmbindStage` which extends a normal `stage`, and adds some convenient abstractions to test `embind11` built modules. If you don't have a reason to dig, you should probably use a `EmbindStage`.
The `TestUtil` library provides `EmbindStage` which extends a normal `stage`, and adds some convenient abstractions to test `embind` built modules. If you don't have a reason to dig, you should probably use a `EmbindStage`.

## Architecture ##

Expand Down
8 changes: 4 additions & 4 deletions tests/testStage/EmscriptenStage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ target_link_libraries(${target_name} PRIVATE embind)
# Export Promise as 'loadm' for module 'm'
# -s MODULARIZE=1 sets it as a promise based load
# Note that this is necessary for preJS to work properly
set_target_properties(
${target_name}
PROPERTIES
set_property(
TARGET ${target_name}
PROPERTY
LINK_FLAGS
"-s MODULARIZE=1 -s EXPORT_NAME=\"loadm\" --pre-js ${CMAKE_CURRENT_LIST_DIR}/src/pre.js"
"-s MODULARIZE=1 -s EXPORT_NAME=\"loadm\" --pre-js ${CMAKE_CURRENT_LIST_DIR}/src/pre.js "
)

0 comments on commit efa5f27

Please sign in to comment.