e410d82680
The built hacked binary segfaults on Linux the moment a native GTK3 dialog (file/folder browse) opens while a GLFW/OpenGL context is live: sqweek/dialog's Linux backend never calls XInitThreads() before gtk_init(), and GLFW's own X11 backend installs a process-wide Xlib error handler that collides with GTK's. Vendor a pinned copy of github.com/sqweek/dialog (New BSD) into modding/sqweek-dialog/ so it can be patched like every other vendored source here: sqweek-dialog-patches/01-xinitthreads.patch adds the missing XInitThreads() call, and hacked-patches/01-use-patched-dialog.patch adds a go.mod replace directive pointing hacked's own sqweek/dialog dependency at that local copy. build-hacked.sh now stages both hacked/ and sqweek-dialog/ into a scratch modding/build/ directory and applies their patch series before compiling, rather than building hacked/ in place; .gitignore picks up that new scratch directory. Also expand modding/README.md: number its existing sections and add a worked "Example: Editing a message" walkthrough covering Static World Data, the Messages window's clipboard-only text editing, saving the Mod Location, and the absolute-path requirement for run.sh's mod-folder argument.
96 lines
4.3 KiB
Bash
Executable File
96 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Compiles modding/hacked/ for Linux and Windows (amd64), entirely offline -
|
|
# every Go module dependency was already fetched into the build-image at
|
|
# image-build time (see Dockerfile). Baked into the image at
|
|
# /usr/local/bin/build-hacked.sh (see Dockerfile's CMD) - run via
|
|
# ../hacked-build-run-image.sh, which bind-mounts modding/ at /workspace, not
|
|
# directly.
|
|
#
|
|
# Does not follow hacked/build.sh (its own upstream build script): that script
|
|
# assumes hacked/ is its own git checkout (it derives its version from `git
|
|
# describe --tags`), which isn't true here - hacked/ is a vendored snapshot,
|
|
# not a git submodule, so `git describe` there would silently pick up
|
|
# *questshock's* tags instead. Version is a plain build-date string instead.
|
|
set -euo pipefail
|
|
|
|
MODDING_ROOT="$(pwd)"
|
|
OUT_DIR="$MODDING_ROOT/dist"
|
|
SCRATCH_DIR="$MODDING_ROOT/build"
|
|
HACKED_SRC="$SCRATCH_DIR/hacked"
|
|
DIALOG_SRC="$SCRATCH_DIR/sqweek-dialog"
|
|
|
|
VERSION="hacked-$(date -u +%Y%m%d)"
|
|
echo "Version: $VERSION"
|
|
|
|
echo "== Preparing scratch, patched copies of hacked/ and sqweek-dialog/ =="
|
|
# hacked/ and sqweek-dialog/ are vendored unmodified (see README.md) - never
|
|
# built or patched in place. hacked-patches/'s go.mod edit points
|
|
# sqweek/dialog at ../sqweek-dialog (a sibling directory here), so both
|
|
# scratch copies must keep that same relative layout.
|
|
rm -rf "$SCRATCH_DIR"
|
|
mkdir -p "$SCRATCH_DIR"
|
|
cp -a "$MODDING_ROOT/hacked" "$HACKED_SRC"
|
|
cp -a "$MODDING_ROOT/sqweek-dialog" "$DIALOG_SRC"
|
|
for p in "$MODDING_ROOT"/hacked-patches/*.patch; do
|
|
patch -p1 -d "$HACKED_SRC" < "$p"
|
|
done
|
|
for p in "$MODDING_ROOT"/sqweek-dialog-patches/*.patch; do
|
|
patch -p1 -d "$DIALOG_SRC" < "$p"
|
|
done
|
|
|
|
rm -rf "$OUT_DIR"
|
|
mkdir -p "$OUT_DIR/linux/hacked" "$OUT_DIR/win/hacked"
|
|
|
|
cd "$HACKED_SRC"
|
|
|
|
echo "== Building Linux amd64 =="
|
|
go build -gcflags "-d=checkptr=0" -ldflags "-X main.version=$VERSION" \
|
|
-trimpath -o "$OUT_DIR/linux/hacked/hacked" .
|
|
|
|
echo "== Preparing the Windows icon/version-info resource =="
|
|
# cmd/link automatically links in a *.syso file sitting in the main package
|
|
# directory during a Windows build - no explicit flag needed, but it does mean
|
|
# generating it (via windres, from hacked.rc/.ico/.exe.manifest) has to happen
|
|
# right here, before go build runs, and be cleaned up after regardless of
|
|
# outcome so it never leaks into a Linux build run from the same checkout.
|
|
WIN_RES_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$WIN_RES_DIR"; rm -f "$HACKED_SRC/main-res.syso"' EXIT
|
|
cp "$HACKED_SRC"/_resources/build/win/* "$WIN_RES_DIR/"
|
|
# No git tag to derive a real version from (hacked/ is a vendored snapshot,
|
|
# not its own checkout) - same date-based fallback hacked/build.sh itself
|
|
# uses when `git describe` fails.
|
|
sed -i "s/§MAJOR/$(date -u +%Y)/;s/§MINOR/$(date -u +%m)/;s/§PATCH/$(date -u +%d)/" \
|
|
"$WIN_RES_DIR/hacked.exe.manifest"
|
|
x86_64-w64-mingw32-windres -o "$HACKED_SRC/main-res.syso" "$WIN_RES_DIR/hacked.rc"
|
|
|
|
echo "== Building Windows amd64 (cross-compiled via mingw-w64) =="
|
|
# -extldflags -static-libgcc/-static-libstdc++: statically links the mingw
|
|
# C/C++ runtime into hacked.exe, the same technique the main project's own
|
|
# Windows cross-build uses (see ../../build-image/Dockerfile) - avoids having
|
|
# to locate and ship libgcc_s_seh-1.dll/libstdc++-6.dll (their exact path
|
|
# depends on the mingw-w64 package's gcc version). libwinpthread-1.dll still
|
|
# needs shipping alongside the .exe; it isn't part of that static link.
|
|
GOOS=windows GOARCH=amd64 CGO_ENABLED=1 \
|
|
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ \
|
|
go build -gcflags "-d=checkptr=0" \
|
|
-ldflags "-X main.version=$VERSION -H=windowsgui -extldflags '-static-libgcc -static-libstdc++'" \
|
|
-trimpath -o "$OUT_DIR/win/hacked/hacked.exe" .
|
|
cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll "$OUT_DIR/win/hacked/"
|
|
|
|
echo "== Copying distribution resources =="
|
|
for os in linux win; do
|
|
packageDir="$OUT_DIR/$os/hacked"
|
|
cp "$HACKED_SRC/LICENSE" "$packageDir/"
|
|
cp -R "$HACKED_SRC/_resources/dist/." "$packageDir/"
|
|
done
|
|
|
|
echo "== Packaging =="
|
|
# $VERSION (hacked-<date>) is already a complete, self-describing name - no
|
|
# separate package-name prefix needed on top of it.
|
|
(cd "$OUT_DIR/linux" && tar -czf "$OUT_DIR/$VERSION.linux64.tgz" hacked)
|
|
(cd "$OUT_DIR/win" && zip -rq "$OUT_DIR/$VERSION.win64.zip" hacked)
|
|
|
|
echo "== Done =="
|
|
echo "Linux: $OUT_DIR/$VERSION.linux64.tgz"
|
|
echo "Windows: $OUT_DIR/$VERSION.win64.zip"
|