/wasm-init

Template for WebAssembly Projects

Primary LanguageJavaScript

wasm-init

Work environment and code generator for WebAssembly projects

wasm-init abstracts the WebAssembly setup and compile process and aims to dramatically simplify the development workflow.

Install

This package requires that you have Emscripten installed on your machine. You can get it like so:

git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install sdk-incoming-64bit binaryen-master-64bit
./emsdk activate sdk-incoming-64bit binaryen-master-64bit

(Note, that the install will take a while. More information is here.)

The best way to install this module is through npm via npm install wasm-init.

Use

At the heart of wasm-init is the wasm.config.js file, which takes Emscripten's compile process and breaks it down into configurable elements. To compile C++ to WASM with Emscripten, you need at bare minimum the following properties:

// wasm.config.js
module.exports = {
  emscripten_path: './../emsdk',
  inputfiles: [
    'lib.cpp',
  ],
  outputfile: 'lib.js',
  flags: [
    '-s WASM=1',
  ],
};

emscripten_path is the relative path to the emsdk directory, from your project folder. (In the above case, we would expect Emscripten to be located in the same parent-directory as the project.)

If you want to automate this process you can set up a few scripts in your project's package.json file:

...
  "scripts": {
    "wasm-init": "wasm-init",
    "compile": "wasm-compile",
    "start": "gulp"   // optional, for hot-reloading
  }
...

Templates

These scripts make the module's functionality accessible. Be aware that npm run wasm-init will create several files and folders inside your project directory. This is your fastest route to a working project setup, however, you can also set up all the files manually, if you so desire.

Custom

The best way to a custom setup is to start with just the wasm.config.js file (you can generate it with npm run wasm-init minimal), and enter the emcc_path, inputfiles, outputfile, and flags according to your needs. When you run npm run wasm-init build, it will generate those files for you.

To compile, simply use npm run compile, which will take your C++ code and output a JavaScript file with Emscripten bindings, as well as the sought after .wasm file. To take advantage of wasm-init's easy loading mechanism for WebAssembly modules, you will need the wrapper file loadWASM.js. The wasm module is from there returned by a promise. Making the module accessible to your application is as easy as the following:

let m = {}
loadWASM().then(wasmModule => {
  m = wasmModule;
  m._myFunc(); // this is the call to the C++ function myFunc();
});

When you want to export individual functions from C++ to WASM, you can do this with the exported_functions property in wasm.config.js:

...
  exported_functions: [
    '_myFunc',
  ]
...

It is required to prepend the C++ function names with an underscore!,


If you are on board with wasm-init's automation, the quickest road to success would be: npm run wasm-init emcc_path=./../emsdk (modify path accordingly). This will set Emscripten's file path in the wasm.config.js file automatically. This will also install and compile all necessary files, including a server.js, index.js and index.html file, that are already setup to include WASM in the browser.
(Executing npm run wasm-init will overwrite any files that may already be there, as does npm run wasm-init build! ).

If you now run your browser (either manually or with gulp), and go to localhost:3000, open up the console, and you should see the message from the C++ file printed.

Flags

The following flags for npm run wasm-init are usable:

build - builds files according to instructions in wasm.config.js

minimal - only creates the wasm.config.js file

no-wrapper - no wrapper (loadWASM.js) file

no-cpp - no C++ file

no-indexjs - no index.js file

no-html - no html file

no-server - no server.js file


If you want built-in hot-reloading functionality, via gulp and browser-sync, just add the flag

hot .

Note, that this will install the gulp and browser-sync packages automatically. This will also generate a gulpfile.js file, which is already setup to work with the template code.


Lastly,

npm run wasm-init clean

will delete the autogenerated files, except wasm.config.js .

npm run wasm-init clean-all

will delete all autogenerated files. Please use it carefully!


Collaborators: Deep Pulusani, Shahrod Khalkhali, Matthias Wagner