Private
Public Access
138 lines
5.0 KiB
Bash
Executable File
138 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")"
|
|
cd ..
|
|
|
|
BUILDMODE=${1:-release}
|
|
case "$BUILDMODE" in
|
|
debug)
|
|
OPT_FLAG="O0"
|
|
DEBUG_FLAGS="-g"
|
|
;;
|
|
release)
|
|
OPT_FLAG="O2"
|
|
DEBUG_FLAGS=""
|
|
;;
|
|
*)
|
|
printf 'Usage: %s [debug|release]\n' "$0" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
GF="bearer_fastcgi"
|
|
|
|
mkdir -p bin/tmp bin/assets bin/wasm work
|
|
build_mode_file="bin/.build_mode"
|
|
exec 9>bin/.build.lock
|
|
flock 9
|
|
if [[ ! -r "$build_mode_file" || "$(<"$build_mode_file")" != "$BUILDMODE" ]]; then
|
|
printf '%s\n' "$BUILDMODE" > "$build_mode_file"
|
|
fi
|
|
build_tmp_files=()
|
|
cleanup_build_tmp() {
|
|
((${#build_tmp_files[@]} == 0)) || rm -f "${build_tmp_files[@]}"
|
|
}
|
|
trap cleanup_build_tmp EXIT
|
|
|
|
COMPILER="clang++"
|
|
# -rdynamic is a link-time flag; the -c compiles below do not need it.
|
|
FLAGS="$DEBUG_FLAGS -w -Wall -$OPT_FLAG -std=c++20 -fpermissive -fuse-ld=lld"
|
|
|
|
# Wasmtime C++ API — needed only by the wasm backend object (src/wasm).
|
|
WASMTIME_HOME=${WASMTIME_HOME:-/opt/wasmtime}
|
|
WASM_FLAGS="-I$WASMTIME_HOME/include"
|
|
PACKAGE_WASMTIME_RPATH='$ORIGIN/../../../../opt/wasmtime/lib'
|
|
WASM_LIBS="-L$WASMTIME_HOME/lib -Wl,-rpath,$WASMTIME_HOME/lib -Wl,-rpath,$PACKAGE_WASMTIME_RPATH -lwasmtime"
|
|
|
|
LIBS="-ldl -lm -lpthread -lpcre2-8 -lcrypto `mysql_config --cflags --libs` $WASM_LIBS"
|
|
SRCFLAGS="-D EXEC_NAME=\"$GF\" -D PLATFORM_NAME=\"linux\""
|
|
|
|
# The runtime is split into separately-compiled objects so an edit to one
|
|
# module no longer recompiles the others (notably: editing the wasm backend
|
|
# does not recompile the rest, and vendored SQLite is built once):
|
|
# bin/sqlite3.o vendored SQLite amalgamation (depends only on its own source)
|
|
# bin/wasm.o wasm backend + worker + wasmtime.hh (src/wasm)
|
|
# bin/main.o linux_fastcgi.cpp + the bearer_lib core amalgamation
|
|
# All link into the single -rdynamic binary. Delete bin/*.o to force a clean
|
|
# rebuild.
|
|
|
|
# Rebuild $1 if it is missing or anything under the remaining find-args is newer.
|
|
needs_rebuild() {
|
|
local obj="$1"; shift
|
|
[ ! -f "$obj" ] && return 0
|
|
# Compare files only. A directory's own mtime changes whenever a temporary
|
|
# file appears inside it, which is not a source change.
|
|
[ -n "$(find "$@" -type f -newer "$obj" -print -quit 2>/dev/null)" ] && return 0
|
|
return 1
|
|
}
|
|
|
|
# Native Capy compiler CLI. The same src/capy compiler implementation is also
|
|
# linked into Bearer below; this executable is the operator/build interface.
|
|
if needs_rebuild bin/capyc src/capy src/lib/markup-context.h scripts/build_capy.sh "$build_mode_file"; then
|
|
echo "Compiling native Capy compiler..."
|
|
bash scripts/build_capy.sh bin/capyc "$BUILDMODE"
|
|
else
|
|
echo "Reusing bin/capyc"
|
|
fi
|
|
python3 scripts/generate_capy_doc_signatures.py --capyc bin/capyc --check
|
|
|
|
# core.wasm: guest runtime loaded by the native wasm backend.
|
|
if needs_rebuild bin/wasm/core.wasm src/wasm/core.cpp src/wasm/abi.h src/lib src/wasm/core_hostcalls.syms src/wasm/core_libc_exports.syms scripts/build_core_wasm.sh "$build_mode_file"; then
|
|
echo "Compiling wasm core..."
|
|
bash scripts/build_core_wasm.sh || exit 1
|
|
else
|
|
echo "Reusing bin/wasm/core.wasm"
|
|
fi
|
|
|
|
# SQLite: vendored C, depends only on its own source (not our headers).
|
|
if needs_rebuild bin/sqlite3.o src/3rdparty/sqlite/sqlite3.c src/3rdparty/sqlite/sqlite3.h "$build_mode_file"; then
|
|
echo "Compiling SQLite..."
|
|
tmp="bin/sqlite3.o.tmp.$$"
|
|
build_tmp_files+=("$tmp")
|
|
clang $DEBUG_FLAGS -$OPT_FLAG -fPIC \
|
|
-DSQLITE_THREADSAFE=1 \
|
|
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
|
|
-DSQLITE_DQS=0 \
|
|
-DSQLITE_DEFAULT_FOREIGN_KEYS=1 \
|
|
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
|
|
-c src/3rdparty/sqlite/sqlite3.c -o "$tmp" 2>&1
|
|
mv "$tmp" bin/sqlite3.o
|
|
else
|
|
echo "Reusing bin/sqlite3.o"
|
|
fi
|
|
|
|
# wasm backend object: the wasm sources plus the lib headers it includes for
|
|
# declarations (not the lib .cpp — those are compiled into main.o).
|
|
if needs_rebuild bin/wasm.o src/wasm src/lib/*.h "$build_mode_file"; then
|
|
echo "Compiling wasm backend..."
|
|
tmp="bin/wasm.o.tmp.$$"
|
|
build_tmp_files+=("$tmp")
|
|
time -p $COMPILER -c src/wasm/wasm_module.cpp $SRCFLAGS $FLAGS $WASM_FLAGS -o "$tmp" 2>&1
|
|
mv "$tmp" bin/wasm.o
|
|
else
|
|
echo "Reusing bin/wasm.o"
|
|
fi
|
|
|
|
# main object: the FastCGI entrypoint + the bearer_lib core amalgamation. Depends
|
|
# on linux_fastcgi.cpp, the whole lib tree, fcgicc, and the wasm backend header
|
|
# (its only view of the wasm object) — but not the wasm .cpp sources.
|
|
if needs_rebuild bin/main.o src/linux_fastcgi.cpp src/lib src/capy src/fastcgi src/wasm/backend.h src/wasm/abi.h "$build_mode_file"; then
|
|
echo "Compiling main..."
|
|
tmp="bin/main.o.tmp.$$"
|
|
build_tmp_files+=("$tmp")
|
|
capy_compiler_build_id=$(sha256sum src/capy/*.cpp src/capy/*.h src/lib/compiler.cpp src/lib/markup-context.h | sha256sum | awk '{print $1}')
|
|
time -p $COMPILER -c src/linux_fastcgi.cpp $SRCFLAGS $FLAGS \
|
|
"-DCAPY_COMPILER_BUILD_ID=\"$capy_compiler_build_id\"" -o "$tmp" 2>&1
|
|
mv "$tmp" bin/main.o
|
|
else
|
|
echo "Reusing bin/main.o"
|
|
fi
|
|
|
|
echo "Linking..."
|
|
binary_tmp="bin/$GF.linux.bin.tmp.$$"
|
|
build_tmp_files+=("$binary_tmp")
|
|
$COMPILER -rdynamic bin/main.o bin/wasm.o bin/sqlite3.o $FLAGS $LIBS -o "$binary_tmp" 2>&1
|
|
test -s "$binary_tmp"
|
|
chmod 0755 "$binary_tmp"
|
|
mv "$binary_tmp" "bin/$GF.linux.bin"
|
|
ls -lh "bin/$GF.linux.bin"
|