Skip to content
kripken edited this page Nov 15, 2011 · 46 revisions

Building Projects

Building large projects with Emscripten can generally be very simple, the process looks like

   emconfiguren.py ./configure
   make
   emscripten.py project.bc > project.js

That is, you run configure and make pretty much normally, the only changes being running configure through tools/emconfiguren.py (which tells configure and later make to use clang in a way that generates proper LLVM bitcode), and running emscripten.py afterwards to convert the LLVM bitcode to JS.

For more details, see the emmaken tool (tools/emmaken.py), the latest docs are inside that file.

Examples

You can see how the large tests in tests/runner.py are built - the C/C++ projects are built using configure, make and so forth (using emmaken.py). Specifically, the large tests include: freetype, openjpeg, zlib and poppler.

Also worth looking at the build scripts in the following projects:

The documentation below gives more low-level details of the process, most of which you do not need if you use emmaken.py (but it might help to understand things).

Detailed Overview

  • The basic idea is replacing the normal compiler with Clang or llvm-gcc, and telling it to emit LLVM bitcode. Also replace the linker with llvm-link.

    • In CMake this can be done with:

          SET(CMAKE_C_COMPILER "/..PATH../llvm-gcc")
          SET(CMAKE_CXX_COMPILER "/..PATH../llvm-g++")
          SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -emit-llvm)`
          SET(CMAKE_LINKER "/..PATH../llvm-link")
          SET(CMAKE_CXX_LINKER "/..PATH../llvm-link")
          SET(CMAKE_C_LINK_EXECUTABLE "/..PATH../llvm-link")
          SET(CMAKE_CXX_LINK_EXECUTABLE "/..PATH../llvm-link")
          SET(CMAKE_AR "/..PATH../llvm-link")
          SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -S -o <TARGET> <LINK_FLAGS> <OBJECTS>")
          SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -S -o <TARGET> <LINK_FLAGS> <OBJECTS>")
          SET(CMAKE_RANLIB "echo") # Hackish way to disable it
      
    • In a Makefile, this can be done with:

          C = /..PATH../llvm-gcc
          CXX = /..PATH../llvm-g++
          LINKER = /..PATH../llvm-link
          CXX_LINKER = /..PATH../llvm-link
      
          # Undefining architecture stuff means code will not generate ASM
          CXXFLAGS=' -emit-llvm -U__i386__ -U__x86_64__'
      
  • Build the project using its normal build system, makefiles, etc. Note that it might fail if it tries to generate executables; you should probably just create libraries. Use make VERBOSE=1 to see the commands being run, so you can make sure you are using the right compiler, etc.

  • Run llvm-link to combine libraries.

  • Compile the generated .bc file using Emscripten.

Other Tips

  • If you manually link your .bc files yourself, do NOT use llvm-ld to link your files. It will also optimize them, in potentially dangerous ways (for us). Instead, use llvm-link.
Clone this wiki locally