TLDR When linking against a static compiled library version of Box2D compilation fails but when including the actual .o files of the Box2D compilation, it works.
I am trying to compile a c++ program that uses the Box2D physics library to webassmbly, using the emscripten tooling.
I can reproduce my issue by trying to compile the HelloWorld example from the Box2D project:
mkdir -p /tmp/demo && cd /tmp/demo
git clone [email protected]:erincatto/Box2D.git
cd Box2D
# The Box2D library its self uses [premake5][3] to generate makefiles.
premake5 gmake
cd Build
# Use Emscripten's emake command
emmake make Box2D
> ...
> Creating bin/x86_64/Debug
> Linking Box2D
ls bin/x86_64/Debug
> libBox2D.a
# Now try and build HelloWorld.cpp using emcc
cd ../HelloWorld
emcc -I ../ -l libBox2D HelloWorld.cpp -L ../Build/bin/x86_64/Debug -std=c++17 -o HelloWorld.js
> error: undefined symbol: _ZN14b2PolygonShape8SetAsBoxEff
However, if instead of including the .a file and linking to libBox2D, I include the *.o files of the Box2D compilation, it compiles just fine.
emcc -I ../ -std=c++17 HelloWorld.cpp ../Build/obj/x86_64/Debug/Box2D/*.o -o HelloWorld.js
node HelloWorld.js
> 0.00 4.00 0.00
> 0.00 3.99 0.00
> 0.00 3.98 0.00
> ...
What is strange is that when I run nm I can see that the symbol is in the .a file.
nm ../Build/bin/x86_64/Debug/libBox2D.a | grep _ZN14b2PolygonShape8SetAsBoxEff`
> -------- T _ZN14b2PolygonShape8SetAsBoxEff
You probably don't want to compile Box2D from the original source. Due to the difference in the environment, some frameworks like Box2D need to be ported for Emscripten environment.
Luckily there is an Emscripten port of Box2D, including detailed instruction on how to build it. This port is maintained by Alon Zakai, the author of Emscripten.