flan/vendor/raylib/build-web.sh
Joseph Ferano f51559030a raylib for the browser is built rather than installed
No emscripten port provides raylib — emcc --show-ports offers contrib.glfw3
and nothing else nearby — so build-web.sh clones raylib at the 5.5 tag and
compiles its seven modules with -DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2 into
one archive under vendor/raylib/web, which is gitignored along with the
checkout it came from.

5.5 because that is the tag whose .so.550 the host links. raylib.flan carries
raylib's struct layouts and enum values, and two targets built from different
raylibs would disagree about them without saying so.

rglfw.c is not among the modules: the web platform uses emscripten's own GLFW
port, which is why link carries @web -sUSE_GLFW=3. No headers are installed,
for the same reason the host build needs none — the generated shim declares
the prototypes it uses.

link now names the host library under @native and the archive under @web,
through ${FLAN_RAYLIB_WEB}, so a web build with the variable unset is refused
with the name of the variable rather than a page of undefined GLFW symbols.
The one thing this costs: a wasi build that reaches raylib now fails on
undefined symbols instead of on the missing -l:libraylib.so.550.
2026-09-12 10:45:27 +07:00

77 lines
2.6 KiB
Bash

#!/bin/sh
# raylib, built for the browser.
#
# The host half of this package needs no build: Fedora ships libraylib.so.550
# and `link` names it. The browser has no such thing, so the archive has to be
# made here, once, out of raylib's own sources with emscripten's clang.
#
# Pinned to the tag whose shared library the host links — 5.5 against
# libraylib.so.550 — because `raylib.flan` carries struct layouts and enum
# values that are raylib's, not ours, and a build where the two targets are
# different raylibs would disagree about them silently.
#
# The output is a plain static archive plus nothing else: no headers are
# installed, because the generated FFI shim declares the prototypes it uses
# (see BUILT.md, "No raylib headers are needed").
#
# sh vendor/raylib/build-web.sh
#
# It prints the line to export. `vendor/raylib/link` points at the archive
# through ${FLAN_RAYLIB_WEB}, and a web build that names raylib with the
# variable unset is refused by name rather than met at the linker.
#
# Environment:
# FLAN_RAYLIB_TAG the raylib tag to build (default 5.5)
# FLAN_RAYLIB_WEB_DIR where to put it (default vendor/raylib/web)
# FLAN_RAYLIB_SRC an existing raylib checkout to build instead of cloning
set -eu
tag=${FLAN_RAYLIB_TAG:-5.5}
here=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
out=${FLAN_RAYLIB_WEB_DIR:-$here/web}
archive=$out/libraylib-$tag.a
command -v emcc > /dev/null 2>&1 || {
echo "build-web.sh: no emcc on PATH. Source an emsdk's emsdk_env.sh." >&2
exit 1
}
if [ -f "$archive" ]; then
echo "already built: $archive" >&2
else
mkdir -p "$out"
if [ -n "${FLAN_RAYLIB_SRC:-}" ]; then
src=$FLAN_RAYLIB_SRC
else
src=$out/raylib-$tag
[ -d "$src" ] || git clone --depth 1 --branch "$tag" \
https://github.com/raysan5/raylib "$src"
fi
objs=$out/obj-$tag
rm -rf "$objs"
mkdir -p "$objs"
# GRAPHICS_API_OPENGL_ES2 is what WebGL is. PLATFORM_WEB makes rcore.c
# include platforms/rcore_web.c, whose WindowShouldClose() is an
# emscripten_sleep that returns false — see BUILT.md on why that is the whole
# reason a Flan `until` loop needs no rewriting for the browser.
#
# rglfw.c is not in the list: the web platform uses emscripten's own GLFW
# (-sUSE_GLFW=3, in `link`), not a compiled-in one.
for m in rcore rshapes rtextures rtext rmodels raudio utils; do
[ -f "$src/src/$m.c" ] || continue
echo " emcc $m.c" >&2
(cd "$src/src" && emcc -c -O2 -std=gnu99 \
-DPLATFORM_WEB -DGRAPHICS_API_OPENGL_ES2 \
-I. -Iexternal/glfw/include \
"$m.c" -o "$objs/$m.o")
done
emar rcs "$archive" "$objs"/*.o
rm -rf "$objs"
fi
echo
echo "export FLAN_RAYLIB_WEB=$archive"