Add Windows cross-compilation via MinGW, and fix Docker build permission
build / build (push) Successful in 3m5s
build / build (push) Successful in 3m5s
issues on vboxsf-mounted checkouts New `make dist-win`/`package-win` targets (folded into `dist`/`package` alongside the renamed `dist-linux`/`package-linux`) cross-compile systemshock.exe via MinGW, using prebuilt SDL2/SDL2_mixer/GLEW/ fluidsynth-lite baked into the build-image - no Windows machine or Wine needed to build it, confirmed working and playable on a real Windows machine. dist-win/ ships DLLs flat alongside the exe plus a new res/run.bat launcher, packaged into a .zip the same way dist/ becomes a .tar.gz. Also fixes three build-image bugs hit while testing on a VirtualBox vboxsf-mounted checkout: build-engine.sh/docker-entrypoint.sh losing their execute bit (chmod +x on restrictive source perms), the container user missing access to /workspace's supplementary vboxsf group, and cp -a failing on symlink/hard-link creation (vboxsf doesn't support either) - now falls back to dereferencing copies when detected. Also adds Docker/zip/etc. prerequisites to the README for both the desktop and Quest builds.
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env bash
|
||||
# Cross-compiles engine/ (the vendored Shockolate snapshot) for Windows
|
||||
# (x86_64) via MinGW, against the dependencies prebuilt into this image at
|
||||
# /opt/prebuilt/win - no network access needed. engine/CMakeLists.txt
|
||||
# already has working WIN32/MINGW branches (the upstream Shockolate
|
||||
# project's own build_win64.sh/appveyor.yml build the same way, natively
|
||||
# on Windows via Git Bash/MinGW; this cross-compiles the same branches
|
||||
# fully offline and reproducibly from Linux instead), so no source
|
||||
# patching is needed, unlike the Quest build's android/engine-patches/.
|
||||
#
|
||||
# Builds from a scratch copy of engine/ (like android/engine-patches/
|
||||
# does for the Quest build) rather than engine/ itself: its BUNDLED
|
||||
# dependency paths (build_ext/built_sdl etc.) and in-source CMake cache
|
||||
# are relative to/inside the source tree, and would otherwise collide
|
||||
# with the Linux desktop build's own build_ext/CMakeCache.txt (see
|
||||
# build-engine.sh) if both are built from the same checkout, as `make
|
||||
# dist` (dist-linux + dist-win) does.
|
||||
#
|
||||
# Must be run with the repo root as the working directory - either via
|
||||
# ../run-image.sh, or directly when already inside this image (see the
|
||||
# Makefile's `engine-win` target, which picks whichever of these
|
||||
# applies, same as `engine`).
|
||||
#
|
||||
# Output lands in engine/.build-output-win/: systemshock.exe, the DLLs
|
||||
# it needs at runtime, and a default MIDI soundfont - everything the
|
||||
# root Makefile needs to assemble dist-win/.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(pwd)"
|
||||
SCRATCH_ENGINE="$REPO_ROOT/build/win-engine"
|
||||
OUT_DIR="$REPO_ROOT/engine/.build-output-win"
|
||||
|
||||
echo "== Preparing a scratch copy of engine/ for the Windows cross-build =="
|
||||
rm -rf "$SCRATCH_ENGINE"
|
||||
mkdir -p "$(dirname "$SCRATCH_ENGINE")"
|
||||
|
||||
# See build-engine.sh for why this detection is needed (e.g. a VirtualBox
|
||||
# vboxsf shared folder refusing to create symlinks or preserve hard-link
|
||||
# relationships) - applied here too since build/ is under the same
|
||||
# bind-mounted repo checkout.
|
||||
CP_FLAGS=(-a)
|
||||
mkdir -p "$(dirname "$SCRATCH_ENGINE")/.symlink-test-dir"
|
||||
if ! ln -s test-target "$(dirname "$SCRATCH_ENGINE")/.symlink-test-dir/test" 2>/dev/null; then
|
||||
echo "(destination filesystem doesn't support symlinks - copying real file content instead)"
|
||||
CP_FLAGS=(-a --dereference --no-preserve=links)
|
||||
fi
|
||||
rm -rf "$(dirname "$SCRATCH_ENGINE")/.symlink-test-dir"
|
||||
|
||||
cp "${CP_FLAGS[@]}" "$REPO_ROOT/engine" "$SCRATCH_ENGINE"
|
||||
cd "$SCRATCH_ENGINE"
|
||||
|
||||
# If engine/ has ever been built in-source directly (`make dist`/`make
|
||||
# engine` - see build-engine.sh), that leftover CMakeCache.txt etc. just
|
||||
# got copied along verbatim - and it still points at the real engine/
|
||||
# path, not this scratch copy, which CMake refuses to configure against
|
||||
# ("directory is different than the directory where CMakeCache.txt was
|
||||
# created"). Same artifact list as .gitignore's "Engine build artifacts"
|
||||
# section.
|
||||
rm -rf build_ext CMakeCache.txt CMakeFiles cmake_install.cmake Makefile \
|
||||
systemshock src/Libraries/CMakeFiles
|
||||
|
||||
echo "== Wiring up prebuilt SDL2/SDL2_mixer/GLEW/fluidsynth-lite (Windows/MinGW) from the image =="
|
||||
rm -rf build_ext
|
||||
mkdir -p build_ext
|
||||
cp "${CP_FLAGS[@]}" /opt/prebuilt/win/sdl2 build_ext/built_sdl
|
||||
cp "${CP_FLAGS[@]}" /opt/prebuilt/win/sdl2_mixer build_ext/built_sdl_mixer
|
||||
cp "${CP_FLAGS[@]}" /opt/prebuilt/win/glew build_ext/built_glew
|
||||
# engine/CMakeLists.txt's BUNDLED FluidSynth mode hardcodes
|
||||
# build_ext/fluidsynth-lite/src as the library search path (matching the
|
||||
# desktop Linux in-source build's own output layout) - same lib/ -> src/
|
||||
# remapping build-image/prepare-android-project.sh does for the Quest
|
||||
# build's own prebuilt fluidsynth-lite.
|
||||
mkdir -p build_ext/fluidsynth-lite/src build_ext/fluidsynth-lite/include
|
||||
cp "${CP_FLAGS[@]}" /opt/prebuilt/win/fluidsynth-lite/lib/. build_ext/fluidsynth-lite/src/
|
||||
cp "${CP_FLAGS[@]}" /opt/prebuilt/win/fluidsynth-lite/include/. build_ext/fluidsynth-lite/include/
|
||||
|
||||
echo "== Configuring (CMake, MinGW cross-compile, BUNDLED SDL2/SDL2_mixer/FluidSynth) =="
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="$MINGW_TOOLCHAIN_FILE" \
|
||||
-DENABLE_SDL2=BUNDLED -DENABLE_SOUND=BUNDLED -DENABLE_FLUIDSYNTH=BUNDLED .
|
||||
|
||||
echo "== Compiling =="
|
||||
make -j"$(nproc)" systemshock
|
||||
|
||||
echo "== Assembling engine/.build-output-win =="
|
||||
rm -rf "$OUT_DIR"
|
||||
mkdir -p "$OUT_DIR"
|
||||
cp systemshock.exe "$OUT_DIR/"
|
||||
# Only SDL2.dll/SDL2_mixer.dll themselves - not SDL2_mixer's own bundled
|
||||
# codec DLLs (libvorbis, libmodplug, libopus, ...), matching what
|
||||
# engine/'s own upstream Windows build script (build_win64.sh) ships:
|
||||
# Shockolate only ever calls Mix_LoadWAV_RW/Mix_HookMusic (same as the
|
||||
# Quest build - see build-image/Dockerfile's Android layer comment),
|
||||
# never loading the OGG/MOD/MP3 game data those codecs would be for.
|
||||
cp build_ext/built_sdl/bin/SDL2.dll build_ext/built_sdl_mixer/bin/SDL2_mixer.dll "$OUT_DIR/"
|
||||
cp build_ext/built_glew/lib/glew32.dll "$OUT_DIR/"
|
||||
cp build_ext/fluidsynth-lite/src/*.dll "$OUT_DIR/"
|
||||
# libgcc/libstdc++ are statically linked (see the Dockerfile's
|
||||
# MINGW_TOOLCHAIN_FILE), but fluidsynth-lite/SDL2 still pull in the
|
||||
# MinGW pthread emulation dynamically.
|
||||
cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll "$OUT_DIR/"
|
||||
cp /opt/prebuilt/soundfont/default.sf2 "$OUT_DIR/soundfont.sf2"
|
||||
|
||||
echo "== Done =="
|
||||
echo "Binary: $OUT_DIR/systemshock.exe"
|
||||
echo "DLLs: $OUT_DIR/*.dll"
|
||||
echo "Soundfont: $OUT_DIR/soundfont.sf2"
|
||||
Reference in New Issue
Block a user