-
Notifications
You must be signed in to change notification settings - Fork 0
Dynamic linking
In general it is recommended to build everything together at once. This lets the compiler optimize things better, and JavaScript engines can run it more quickly as well. However, in some cases you might want to compile separate files, perhaps to reduce initial download size, etc. For that, Emscripten has support for two forms of dynamic linking.
The dlopen
family of functions let you load a library at runtime and access symbols from it. To use this, compile the library with BUILD_AS_SHARED_LIB=1
, and then use dlopen
normally. See the dlfcn
family of tests in the test runner for examples.
By 'runtime linking' we mean the procedure where, when you load the main file, it automatically loads one or more additional libraries that were compiled separately. We don't support static linking of JS files (you can link the LLVM bitcode statically before conversion to JS, of course), but this comes pretty close to it. It's useful if you want to compile files separately (for example, if you repeatedly compile one file for debugging purposes, and don't want to compile everything every time).
To use runtime linking, like the library or libraries with BUILD_AS_SHARED_LIB=2
, and the main file with RUNTIME_LINKED_LIBS=["lib1", "lib2"]
where lib1, lib2 are the libraries (the main file should be compiled with BUILD_AS_SHARED_LIB=0
, of course). When you then run the main file, it will load the libraries and they will all work together. See the runtimelink test in the test runner for a concrete example.
You will probably need to run emcc with -s LINKABLE=1
, for both the main file and libraries, in order to prevent dead code elimination. Otherwise, the functions one file needs in another might be removed because in that file it isn't clear they are needed. An alternative is to mark the functions that are actually needed, see the entry on dead code elimination in the FAQ.
You should not use closure compiler to optimize and minify the code when using this linking approach, as it renames symbols and prevents each file from finding what it needs in the other. You can still run all other optimizations though, -O2 --closure 0
.
Note: Runtime linking relies on the dynamic aspects of JavaScript to insert new symbols into the global scope from the libraries. For some reason we still need to investigate, it doesn't work in node.js, but does everywhere else. (We can probably fix this, if necessary - file an issue if you need it.)