Skip to content

Commit

Permalink
Merge pull request #28 from Tolc-Software/latestdeps
Browse files Browse the repository at this point in the history
Latestdeps
  • Loading branch information
srydell committed May 11, 2022
2 parents 9b6f975 + ed0e8f9 commit d201639
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 4 deletions.
8 changes: 4 additions & 4 deletions 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.6.0
VERSION 0.6.1
LANGUAGES CXX)

configure_file(docs/ReleaseNotes/version.in
Expand Down Expand Up @@ -31,17 +31,17 @@ include(${modules}/Sanitizers.cmake)
include(${modules}/StaticAnalyzers.cmake)

include(${modules}/GetFrontend.cmake)
get_frontend(NAME Frontend.py VERSION v0.6.0)
get_frontend(NAME Frontend.py VERSION v0.6.1)
copy_frontend_docs(NAME Frontend.py SRC_DIR ${frontend.py_SOURCE_DIR} COPY_TO
${CMAKE_CURRENT_LIST_DIR}/docs/packaging/docs/python)

get_frontend(NAME Frontend.wasm VERSION v0.5.0)
get_frontend(NAME Frontend.wasm VERSION v0.5.1)
copy_frontend_docs(
NAME Frontend.wasm SRC_DIR ${frontend.wasm_SOURCE_DIR} COPY_TO
${CMAKE_CURRENT_LIST_DIR}/docs/packaging/docs/webassembly)

include(${modules}/GetParser.cmake)
get_parser(VERSION v0.4.1)
get_parser(VERSION v0.5.6)

# Set the include path for the system library in the variable
# We are using the standard library shipped
Expand Down
5 changes: 5 additions & 0 deletions docs/ReleaseNotes/v0.6.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# News #

* Update to Parser v0.5.6
* Update to Frontend.py v0.6.1
* Update to Frontend.wasm v0.5.1
164 changes: 164 additions & 0 deletions docs/packaging/docs/webassembly/quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# 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 [`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` ##

This is a quick guide to using a `C++` library (here called `MyLib`) from `javascript`. We will:

1. Download and use `Tolc`
2. Download and set up `Emscripten`
3. Use the resulting `WebAssembly` from `javascript`

The following works on all supported platforms. On all platforms you need `git` available in your `path`. Commands that should be run from a terminal starts with `$ `, while comments starts with `# `.

### Downloading `Tolc` ###

Just add the following in a `CMakeLists.txt` below where the library you intend to use from `javascript` is defined:

```cmake
# Download Tolc
# Can be ["latest", "v0.2.0", ...]
set(tolc_version latest)
include(FetchContent)
FetchContent_Declare(
tolc_entry
URL https://github.com/Tolc-Software/tolc/releases/download/${tolc_version}/tolc-${CMAKE_HOST_SYSTEM_NAME}.tar.xz
)
FetchContent_Populate(tolc_entry)
set(tolc_DIR ${tolc_entry_SOURCE_DIR}/lib/cmake/tolc)
find_package(
tolc
CONFIG
REQUIRED
)
tolc_create_bindings(
TARGET MyLib
LANGUAGE wasm
OUTPUT wasm-bindings
)
```

Assuming your library is called `MyLib`, and the bindings should be generated to the directory `wasm-bindings`.

### Downloading `Emscripten` ###

In order to compile your library to `WebAssembly`, you need to download the [`Emscripten compiler`](https://emscripten.org/). This is typically done via the `Emscripten SDK`. Navigate to the directory where you want to install and run the following commands:

```shell
# Download SDK
$ git clone https://github.com/emscripten-core/emsdk.git
$ cd emsdk
```

Now follow the specifig commands for your platform.

#### Linux/MacOS ####

From within the `emsdk` directory:

```shell
# Download and install locally
$ ./emsdk install 3.1.3
# Writes configuration file .emscripten
$ ./emsdk activate 3.1.3
```

#### Windows ####

From within the `emsdk` directory:

```shell
# Download and install locally
$ emsdk.bat install 3.1.3
# Writes configuration file .emscripten
$ emsdk.bat activate 3.1.3
```

### Configuring Your Project ###

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:

```shell
# Configures project to build using Emscripten
$ 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:

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

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

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>
...
```

For a complete example you can see the `Tolc-demo` repository: [https://github.com/Tolc-Software/tolc-demo](https://github.com/Tolc-Software/tolc-demo).

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

0 comments on commit d201639

Please sign in to comment.