Take any existing CMake-based C/C++ project, and chances are that you will be able to use Emscripten, and call emcmake cmake, and end up with a JS file that you can run in the browser.

This seems a bit magical, so let’s peek under the hood.

The emcmake shell script is a wrapper for a python script emcmake.py. This is a small script, and the main thing it does is to call cmake with the flag -DCMAKE_TOOLCHAIN_FILE=<path/to/Emscripten.cmake>. Emscripten.cmake is where a lot of the magic happens.

The CMAKE_TOOLCHAIN_FILE variable specifies a path to a “toolchain” file, which is a collection of compilers and utilties to be used by CMake to build the project. Emscripten behaves as a cross compiler in this case.

Emscripten.cmake does a lot of stuff, at a high level, it sets a bunch of variables so that existing C/C++ projects that are not aware of WebAssembly/JavaScript can compile just fine:

With all these setup, when we eventually ask CMake to build the project, individual C/C++ files are compiled using emcc, which generates intermediate Wasm files, and then those files are linked again by emcc, to generate .wasm and .js files.