Compiling racket with emscripten

This is a work-in-progress documentation about building the Racket interpreter to WebAssembly, in order to run it in a browser window.

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
git clone https://github.com/racket/racket.git -b v8.0
cd racket/racket/src
mkdir build
cd build
emconfigure ../configure --enable-bconly --disable-jit --disable-docs --disable-gracket --disable-pthread --disable-futures --disable-places --enable-cgcdefault --disable-foreign --disable-libffi CFLAGS='-s ALLOW_MEMORY_GROWTH=1'
emmake make
make[5]: Entering directory '[...]/racket/racket/src/build/bc'
[...]/emsdk/upstream/emscripten/emcc -I. -I../../bc/include -I../../bc/../version -s ALLOW_MEMORY_GROWTH=1   -DMZ_DONT_USE_JIT  -DUSE_SENORA_GC  -DDONT_USE_FOREIGN -DINITIAL_COLLECTS_DIRECTORY='"'"`cd ../../bc/../../collects; pwd`"'"' -DINITIAL_CONFIG_DIRECTORY='"'"`cd ../../bc/../..; pwd`/etc"'"' -c ../../bc/main.c -o main.o
[...]/emsdk/upstream/emscripten/emcc -o racketcgc main.o  libracket.a libmzgc.a rktio/librktio.a  -ldl -lm  -ldl -lm -rdynamic 
echo racketcgc
racketcgc
make[5]: Leaving directory '[...]/racket/racket/src/build/bc'
make cstartup
make[5]: Entering directory '[...]/racket/racket/src/build/bc'
make cstartup_`./racketcgc -cu ../../bc/src/startup-select.rkt`
/bin/sh: 1: ./racketcgc: Permission denied
make[6]: Entering directory '[...]/racket/racket/src/build/bc'
echo "Bad startup choice, probably an error running startup-select.rkt"
Bad startup choice, probably an error running startup-select.rkt
exit 1

This means that the racketcgc binary was generated as webassembly, and the operating system wasn’t able to run it natively, which is to be expected.

cd bc
emcc -o racketcgc.html main.o  libracket.a libmzgc.a rktio/librktio.a  -ldl -lm  -ldl -lm -rdynamic
emrun racketcgc.html

In the browser we can see that it prints a banner

Welcome to Racket v8.0 [cgc].

And in the browser’s console the errors appear:

exception thrown: longjmp
Uncaught longjmp

Notes