Compile C/C++ into JavaScript with Emscripten and Docker

JavaScript continues its march towards its destiny as the universal programming language, largely due to its cross-platform portability. In previous blog posts, we demonstrated how to cross compile a large, scientific C++ library, ITK, by using cross-compilation capabilities of CMake for a number platforms,

In this post, we will go through the steps to cross-compile ITK to JavaScript and run its test suite. Over a decade of development by hundreds of top-notch research programmers is then immediately accessible to anyone with a web browser.

Edit 2016-10-10: The instructions below now use dockcross. Cross compile for other platforms by replacing dockcross/browser-asmjs with dockcross/linux-armv7, etc.

1) Get the cross-compiling toolchain

As with previous posts, we will use Docker to grab the toolchain:

This Docker image contains of a recent version of CMake and Emscripten, along with Emscripten’s dependencies.

2) Obtain the source and create a build tree

If there is a source tree and build tree, e.g.

3) Build and test

For the purposes of running the test suite, we will add flags for Emscripten that sacrifice run-time performance at the cost of functionality:

Inside the container, the environmental variable CMAKE_TOOLCHAIN_FILE has been configured to point to the toolchain file CMake uses to inform itself about the build environment. Pass this file to CMake during configuration.

The -G Ninja flag tells CMake to use our favorite generator, the Ninja generator.

Emscripten uses NodeJS as the CMAKE_CROSSCOMPILING_EMULATOR; with CMake 3.3 and later, this means NodeJS is used to also run the test suite. For NodeJS to access the file paths passed as command line arguments, the paths must be mounted to the NODEFS file system. ITK’s test driver is instrumented to mount the source tree and build tree when executed.

Start the Experimental dashboard build!

Enjoy ITK!

9 Responses to Compile C/C++ into JavaScript with Emscripten and Docker

  1. Jordi Inglada says:

    Hi,

    Thank you for this very interesting series of posts using Docker. While I understand the interest of cross-compiling for several architectures and OSes to distribute my applications, I don’t really see a use case for the use on the browser. Could you (or someone else) give some examples of those?

    Thank you.

    J.

  2. Matt McCormick says:

    Hi Jordi,

    Yes, please stay tuned for a following post that demonstrates the value of this functionality.

    Thanks,
    Matt

  3. Matt McCormick says:

    Hi Jordi,

    An example using the technology to create interactive figures is presented here:

    http://kitware.com/blog/home/post/942

    Cheers,
    Matt

  4. Juan Prieto says:

    Hello Matt,
    I have set up emscripten in my system and I was able to compile ITK4.8 using ’emmake make’.
    I am trying to build an external project that uses ITK. I’m having trouble in the linking stage. I have messages such as:

    WARNING root: emcc: cannot find library “ITKCommon”

    warning: unresolved symbol: _ZN3itk10DataObject13ResetPipelineEv

    It seems that the liking rules are not passed to emmake.

    Does any one know how to set up the compilation properly?

    Any comments or suggestion will be greatly appreciated.

    Cheers,

    Juan

  5. Matt McCormick says:

    Hello Juan,

    For both, just using emmake is likely insufficient. Try using the CMAKE_TOOLCHAIN_FILE as described above for both builds.

    HTH,
    Matt

  6. Juan Prieto says:

    I am using CMAKE_TOOLCHAIN_FILE but I still have those linking warnings.
    The execution does not work because of it.

    Juan

  7. Matt McCormick says:

    Hi Juan,

    Please post your CMakeLists.txt for your project and the cmake command used to configure your project on the ITK mailing list, and we can follow-up there.

    Thanks,
    Matt

  8. Kevin says:

    Hi! I’m new to docker and cross compiling as well. I was able to pull the cross compiler image from docker. However, I get stuck at step 2. It says something about a dockcross script and that I can’t run it manually. I pulled the linux-arm-v7 cross compiler,too. The problem, however, still persists. Could you suggest a solution? Thanks in advance for your time.

Questions or comments are always welcome!