Skip to content

Commit

Permalink
More documentation about how to use WebAssembly within a web page
Browse files Browse the repository at this point in the history
* Also add blog link
  • Loading branch information
srydell committed Mar 10, 2022
1 parent f696d28 commit c849de3
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 13 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.17)

project(
tolc
VERSION 0.4.0
VERSION 0.4.1
LANGUAGES CXX)

configure_file(docs/ReleaseNotes/version.in
Expand Down
12 changes: 6 additions & 6 deletions cmake/packaging/tolc/tolcCreateTranslation.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,25 @@ function(tolc_create_bindings)
OUTPUT
${ARG_OUTPUT})

if(${ARG_LANGUAGE} MATCHES "python")
if(ARG_LANGUAGE STREQUAL "python")
# NOTE: Variable injected from tolcConfig file
get_pybind11(VERSION ${tolc_pybind11_version})
# Create the python module
pybind11_add_module(${tolc_target_name}
${ARG_OUTPUT}/${ARG_TARGET}_python.cpp)
elseif(${ARG_LANGUAGE} MATCHES "wasm")
elseif(ARG_LANGUAGE STREQUAL "wasm")
# Assumes that the Emscripten toolchain file is used
# Will result in a .js and a .wasm file
add_executable(${tolc_target_name} ${ARG_OUTPUT}/${ARG_TARGET}_wasm.cpp)

# Export Promise as 'loadMyLib' for module 'MyLib'
# -s MODULARIZE=1 sets it as a promise based load
# Note that this is necessary for preJS to work properly
set_target_properties(
${tolc_target_name}
PROPERTIES
set_property(
TARGET ${tolc_target_name}
PROPERTY
LINK_FLAGS
"-s MODULARIZE=1 -s EXPORT_NAME=\"load${ARG_TARGET}\" --pre-js ${ARG_OUTPUT}/pre.js -lembind"
"-s MODULARIZE=1 -s EXPORT_NAME='load${ARG_TARGET}' --pre-js ${ARG_OUTPUT}/pre.js -lembind "
)
else()
error_with_usage(
Expand Down
10 changes: 10 additions & 0 deletions docs/ReleaseNotes/v0.4.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# News #

## Documentation ##

* Add examples on how to use the `WebAssembly` from a web page.

## Minor ##

* Make it easier to add linker flags to `WebAssembly` targets
* More info in the documentation: [https://docs.tolc.io/webassembly/introduction/](https://docs.tolc.io/webassembly/introduction/)
68 changes: 62 additions & 6 deletions docs/packaging/docs/webassembly/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 @@ -29,17 +29,18 @@ FetchContent_Declare(
)
FetchContent_Populate(tolc_entry)
set(tolc_DIR ${tolc_entry_SOURCE_DIR}/lib/cmake/tolc)
find_package(
tolc
CONFIG
PATHS
${tolc_entry_SOURCE_DIR}
REQUIRED)
REQUIRED
)
tolc_create_bindings(
TARGET MyLib
LANGUAGE wasm
OUTPUT wasm-bindings)
OUTPUT wasm-bindings
)
```

Assuming your library is called `MyLib`, and the bindings should be generated to the directory `wasm-bindings`.
Expand Down Expand Up @@ -80,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 @@ -89,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 @@ -103,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).

1 change: 1 addition & 0 deletions docs/packaging/tolc_theme/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
<div class="navbar-end">
<a class="navbar-item is-size-5" href="https://tolc.io">Getting Started</a>
<a id="active-item" class="navbar-item is-size-5" href="https://docs.tolc.io/">Docs</a>
<a class="navbar-item is-size-5" href="https://tolc.io/blog">Blog</a>
<a class="navbar-item is-size-5" href="https://tolc.io/live">Live Demo</a>
<a class="navbar-item is-size-5" href="https://tolc.io/products">Products</a>
<a class="navbar-item is-size-5" href="https://tolc.io/account">Account</a>
Expand Down

0 comments on commit c849de3

Please sign in to comment.