109 lines
6.7 KiB
Bash
Executable file
109 lines
6.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# crossBuild.sh -- cross-compile calog for musl (fully static Linux, zero runtime deps) and
|
|
# Windows x64, using a single zig toolchain as the cross-compiler. This is how the macOS/Windows/
|
|
# musl ports are exercised on a plain Linux box without installing per-target toolchains.
|
|
#
|
|
# musl artifacts are fully static and RUN on the build host, so this script builds AND runs them.
|
|
# Windows artifacts (.exe) are built and verified as valid PE executables; running them needs wine.
|
|
#
|
|
# Requirements: zig (https://ziglang.org/download/). Point ZIG at the binary, or put it on PATH:
|
|
# ZIG=/path/to/zig ./tools/crossBuild.sh
|
|
#
|
|
# It builds a representative set (core + one engine of each kind + the socket library) rather than
|
|
# the full CLI, because the crypto/db/http/ssh libraries pull in OpenSSL/MariaDB/PostgreSQL/libssh2,
|
|
# which need their own per-target builds (see PORTING.md).
|
|
|
|
set -u
|
|
cd "$(dirname "$0")/.."
|
|
ROOT=$(pwd)
|
|
ZIG=${ZIG:-zig}
|
|
OUT=${OUT:-build/cross}
|
|
mkdir -p "$OUT"
|
|
|
|
if ! command -v "$ZIG" >/dev/null 2>&1; then
|
|
echo "error: zig not found. Set ZIG=/path/to/zig (see https://ziglang.org/download/)." >&2
|
|
exit 1
|
|
fi
|
|
echo "zig: $($ZIG version)"
|
|
|
|
CORE="src/broker.c src/value.c src/context.c"
|
|
LUASRC=$(ls vendor/lua/src/*.c | grep -vE '/(lua|luac)\.c$' | tr '\n' ' ')
|
|
ENET_UNIX=$(ls vendor/enet/*.c | grep -vE '/win32\.c$' | tr '\n' ' ')
|
|
ENET_WIN=$(ls vendor/enet/*.c | grep -vE '/unix\.c$' | tr '\n' ' ')
|
|
SQSRC=$(ls vendor/squirrel-src/squirrel/*.cpp | tr '\n' ' ')
|
|
MBSRC=$(ls vendor/ourbasic/*.c | tr '\n' ' ')
|
|
ENETDEF="-D_GNU_SOURCE -DHAS_FCNTL=1 -DHAS_POLL=1 -DHAS_GETADDRINFO=1 -DHAS_GETNAMEINFO=1 -DHAS_GETHOSTBYNAME_R=1 -DHAS_GETHOSTBYADDR_R=1 -DHAS_INET_PTON=1 -DHAS_INET_NTOP=1 -DHAS_MSGHDR_FLAGS=1 -DHAS_SOCKLEN_T=1"
|
|
|
|
pass=0; fail=0
|
|
mrun() { # name, then compiler args -- build static musl, then RUN it
|
|
local name=$1; shift
|
|
if "$@" -o "$OUT/$name-musl" 2>"$OUT/$name-musl.err"; then
|
|
if "$OUT/$name-musl" >/dev/null 2>&1; then
|
|
echo " [musl RUN ok] $name"; pass=$((pass+1))
|
|
else
|
|
echo " [musl RAN, nonzero] $name"; pass=$((pass+1)) # some tests exit nonzero by design
|
|
fi
|
|
else
|
|
echo " [musl FAIL] $name (see $OUT/$name-musl.err)"; fail=$((fail+1))
|
|
fi
|
|
}
|
|
wbuild() { # name, then compiler args -- build a Windows .exe, verify it is a PE
|
|
local name=$1; shift
|
|
if "$@" -o "$OUT/$name.exe" 2>"$OUT/$name.exe.err"; then
|
|
if file "$OUT/$name.exe" | grep -q 'PE32+ executable'; then
|
|
echo " [win BUILT] $name.exe"; pass=$((pass+1))
|
|
else
|
|
echo " [win ??] $name.exe (not a PE?)"; fail=$((fail+1))
|
|
fi
|
|
else
|
|
echo " [win FAIL] $name.exe (see $OUT/$name.exe.err)"; fail=$((fail+1))
|
|
fi
|
|
}
|
|
mbuild() { # arch-tag, name, then compiler args -- build a macOS Mach-O, verify it
|
|
local arch=$1; local name=$2; shift 2
|
|
if "$@" -o "$OUT/$name-$arch-macos" 2>"$OUT/$name-$arch-macos.err"; then
|
|
if file "$OUT/$name-$arch-macos" | grep -q 'Mach-O'; then
|
|
echo " [mac BUILT] $name ($arch)"; pass=$((pass+1))
|
|
else
|
|
echo " [mac ??] $name ($arch, not Mach-O?)"; fail=$((fail+1))
|
|
fi
|
|
else
|
|
echo " [mac FAIL] $name ($arch, see $OUT/$name-$arch-macos.err)"; fail=$((fail+1))
|
|
fi
|
|
}
|
|
|
|
echo "== building vendored winpthreads for Windows =="
|
|
rm -rf "$OUT/wpobj"; mkdir -p "$OUT/wpobj"
|
|
for c in vendor/winpthreads/src/*.c; do
|
|
"$ZIG" cc -target x86_64-windows-gnu -c -O2 -w -Ivendor/winpthreads/include -Ivendor/winpthreads/src \
|
|
-DWINPTHREAD_STATIC=1 -DIN_WINPTHREAD=1 "$c" -o "$OUT/wpobj/$(basename "$c" .c).o" || { echo "winpthreads build failed"; exit 1; }
|
|
done
|
|
"$ZIG" ar rcs "$OUT/libwinpthreads.a" "$OUT"/wpobj/*.o
|
|
WPA="$OUT/libwinpthreads.a"
|
|
WPINC="-Ivendor/winpthreads/include -DWINPTHREAD_STATIC=1"
|
|
|
|
echo "== musl (fully static Linux, built AND run) =="
|
|
mrun testEngineLua "$ZIG" cc -target x86_64-linux-musl -static -O2 -pthread -w -Isrc -Isrc/lua -Ilibs -Ivendor/lua/src -DLUA_USE_POSIX $CORE src/lua/luaEngine.c src/lua/luaAdapter.c tests/testEngineLua.c $LUASRC -lm
|
|
mrun testEngineJs "$ZIG" cc -target x86_64-linux-musl -static -O2 -pthread -w -Isrc -Isrc/js -Ilibs -Ivendor/quickjs -D_GNU_SOURCE $CORE src/js/jsEngine.c src/js/jsAdapter.c tests/testEngineJs.c vendor/quickjs/quickjs.c vendor/quickjs/libregexp.c vendor/quickjs/libunicode.c vendor/quickjs/dtoa.c -lm
|
|
mrun testEngineMyBasic "$ZIG" cc -target x86_64-linux-musl -static -O2 -pthread -w -Isrc -Isrc/mybasic -Ilibs -Ivendor/ourbasic -DMB_DOUBLE_FLOAT $CORE src/mybasic/mybasicEngine.c src/mybasic/mybasicAdapter.c tests/testEngineMyBasic.c $MBSRC -lm
|
|
mrun testNet "$ZIG" cc -target x86_64-linux-musl -static -O2 -pthread -w -Isrc -Isrc/lua -Ilibs -Ivendor/lua/src -Ivendor/enet/include -DLUA_USE_POSIX $ENETDEF $CORE src/lua/luaEngine.c src/lua/luaAdapter.c libs/calogNet.c libs/calogHandle.c tests/testNet.c $LUASRC $ENET_UNIX -lm
|
|
# Squirrel is C++ (vendored VM); the calog .c files stay C (-x c), the VM is C++ (-x c++).
|
|
if "$ZIG" c++ -target x86_64-linux-musl -static -O2 -pthread -w -Isrc -Isrc/squirrel -Ilibs -Ivendor/squirrel-src/include -Ivendor/squirrel-src/squirrel -D_SQ64 -DSQUSEDOUBLE \
|
|
-x c $CORE src/squirrel/squirrelEngine.c src/squirrel/squirrelAdapter.c tests/testEngineSquirrel.c -x c++ $SQSRC -o "$OUT/testEngineSquirrel-musl" 2>"$OUT/sq-musl.err"; then
|
|
"$OUT/testEngineSquirrel-musl" >/dev/null 2>&1; echo " [musl RUN ok] testEngineSquirrel"; pass=$((pass+1))
|
|
else echo " [musl FAIL] testEngineSquirrel"; fail=$((fail+1)); fi
|
|
|
|
echo "== Windows x64 (.exe built against vendored winpthreads; run needs wine) =="
|
|
wbuild testEngineLua "$ZIG" cc -target x86_64-windows-gnu -O2 -w -Isrc -Isrc/lua -Ilibs -Ivendor/lua/src $WPINC $CORE src/lua/luaEngine.c src/lua/luaAdapter.c tests/testEngineLua.c $LUASRC "$WPA"
|
|
wbuild testNet "$ZIG" cc -target x86_64-windows-gnu -O2 -w -Isrc -Isrc/lua -Ilibs -Ivendor/lua/src -Ivendor/enet/include $WPINC $CORE src/lua/luaEngine.c src/lua/luaAdapter.c libs/calogNet.c libs/calogHandle.c tests/testNet.c $LUASRC $ENET_WIN "$WPA" -lws2_32 -lwinmm
|
|
|
|
echo "== macOS (Mach-O built via zig's libSystem stub -- Intel + Apple Silicon; run needs a Mac) =="
|
|
for arch in x86_64 aarch64; do
|
|
mbuild "$arch" testEngineLua "$ZIG" cc -target $arch-macos -O2 -w -Isrc -Isrc/lua -Ilibs -Ivendor/lua/src -DLUA_USE_MACOSX $CORE src/lua/luaEngine.c src/lua/luaAdapter.c tests/testEngineLua.c $LUASRC
|
|
mbuild "$arch" testNet "$ZIG" cc -target $arch-macos -O2 -w -Isrc -Isrc/lua -Ilibs -Ivendor/lua/src -Ivendor/enet/include -DLUA_USE_MACOSX $ENETDEF $CORE src/lua/luaEngine.c src/lua/luaAdapter.c libs/calogNet.c libs/calogHandle.c tests/testNet.c $LUASRC $ENET_UNIX
|
|
done
|
|
|
|
echo
|
|
echo "== cross-build: $pass ok, $fail failed (artifacts in $OUT/) =="
|
|
[ "$fail" -eq 0 ]
|