#!/usr/bin/env bash
# Use this to build -fPIC C or C++ code using zig. I like doing this, since zig is a very
# compact and efficient way to CLANG/LLVM. Unfortunately (in mid 2022), zig doesn't directly
# support building -fPIC code (the flag does nothing), which is of course absolutely required
# to create and use a dynamic library with WebAssembly. Fortunately, zig includes wasm-ld
# and clang, so we can work around this shortcoming. This script does so, basically by
# add a bunch of obscure options to the command line.
#
# TODO: upstream this by improving the way zig handles -target=wasm32-emscripten, or
# some other approach.
#
# Needed on macOS
realpath() {
OURPWD=$PWD
cd "$(dirname "$1")"
LINK=$(readlink "$(basename "$1")")
while [ "$LINK" ]; do
cd "$(dirname "$LINK")"
LINK=$(readlink "$(basename "$1")")
done
REALPATH="$PWD/$(basename "$1")"
cd "$OURPWD"
echo "$REALPATH"
}
ZIG_EXE=`which zig`
ZIG_EXE=`realpath $ZIG_EXE`
ZIG_HOME=`dirname $ZIG_EXE`
#echo "ZIG_EXE=$ZIG_EXE"
INCLUDE="$ZIG_HOME/lib/zig/libc/include"
# On MacOS the includes are in $ZIG_HOME/lib/zig/libc (etc), for some reason
# on Linux it is just $ZIG_HOME/lib/libc, i.e., sometimes there's an extra zig in the path.
if [ ! -d "$INCLUDE" ]
then
INCLUDE="$ZIG_HOME/lib/libc/include"
fi
#echo "INCLUDE=$INCLUDE"
# These are the flags we need to make the -target=wasm32-emscripten actually work
# with what's provided in the zig distribution. Note that we always set -shared,
# the target wasm32-emscripten and -fPIC, since I can't think
# of any reason to be using this script when you wouldn't have those set.
FLAGS="\
-target wasm32-emscripten \
-fPIC \
-isystem $INCLUDE/wasm-wasi-musl \
-isystem $INCLUDE/generic-musl \
-D__wasi__ -D__EMSCRIPTEN_major__=3 -D__EMSCRIPTEN_minor__=1 -D__EMSCRIPTEN_tiny__=16 \
-D_WASI_EMULATED_MMAN -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_PROCESS_CLOCKS -D_WASI_EMULATED_GETPID"
echo "zig $@ $FLAGS"
zig "$@" $FLAGS