Pulling down the emscripten compiler is rather straightforward:
Once you have the project, cd into the directory and have Emscripten install the latest toolchain by issuing the following commands
This comes with a release of the llvm compiler toolchain which we would have to setup as our clang and clang++ compilers.
Fortunately, there’s a handy shell script in the project root that we can use to do just this. It also adds tools from the emsdk to our path for easy access.
Now you should be able to verify that emcc, the emscripten C compiler is available by running the following command.
At this point we are ready to hack around with compiling a C/C++ program. Let’s attempt compiling a file we can call fizzbuzz.cpp with content,
Passing html as the output file extension tells Emscripten to generate an HTML page template bootstrapped to run your code
To compile down to webassembly, all you need to do is add the WASM compiler flag
This will generate a fizzbuzz.wasm module along with fizzbuzz.js to load the wasm module.
While compiling your own native code is pretty cool, Emscripten’s true value comes in including native libraries in your project.
To do this, your libraries have to be compiled into LLVM bitcode.
Compiling them into standard static libraries won’t work. The best candidates for compilation via emscripten are standalone portable libraries. This is because often the result of the build is intended to target the browser. Complex builds with OS specific dependencies will require additional work to port over.
To walk through the process we’ll be building zip; A lightweight portable zip library based on the miniz compression library.
We can begin by cloning the repository and navigating to the directory.
Next we’ll build the library using emscripten wrappers around cmake and make. These replace the default system C/C++ compilers with emscripten during the build process.
At this point we should have an static archive libzip.a that contains the llvm bitcode we need to link against when building our final executable.
Let’s write some code that will be using this library.
Here we’re including a header file from zip so we can use functions built into the project. We’re also including the emscripten header so we can mount the node file system instance. This will allow us to write outside of the emscripten virtual file system.
This mounts the vitual file system path "/fs" to our current working directory. So to write a file foo.txt, we’d need to write it to fs/foo.txt.
Finally, we can now compile our source using em++, the emscripten counterpart to g++ or clang++. Here we statically link to the archive as well as pass it’s path and the zip project’s source folder to include the header files.
This gives us a file zipit.out.js we can execute which creates a zip file containing a single text file as expected.
Building libraries yourself can be quite tedious especially when faced with large projects or situations where a library contains dependencies on other shared libraries. A great example of this would be the popular libpng or SDL which require some work to make compatible with Emscripten. A great initiative underway is the Emscripten ports project that aims to make it easy to add such projects to your builds. For example, adding libpng to your project is as easy as running
You can get a full list of Emscripten ports available by running