a2fb95e57b
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.
408 lines
23 KiB
Docker
408 lines
23 KiB
Docker
# Build environment for the Shockolate (System Shock) engine snapshot in
|
|
# engine/. Everything the engine build needs from the network - SDL2,
|
|
# SDL2_mixer, the fluidsynth-lite MIDI synth, and a General MIDI soundfont -
|
|
# is fetched and built once, here, at image-build time. Rebuild with
|
|
# ../build-image.sh whenever a version below changes.
|
|
#
|
|
# The resulting image needs no network access to compile engine/: the
|
|
# in-container build script (build-image/build-engine.sh) copies the
|
|
# prebuilt pieces below straight into engine/build_ext/, matching the paths
|
|
# engine/CMakeLists.txt's BUNDLED dependency mode expects.
|
|
FROM ubuntu:22.04
|
|
|
|
ARG SDL2_VERSION=2.0.9
|
|
ARG SDL2_MIXER_VERSION=2.0.4
|
|
# EtherTyper/fluidsynth-lite has no releases/tags; pin by commit so the image
|
|
# is reproducible instead of silently picking up upstream changes.
|
|
ARG FLUIDSYNTH_LITE_REF=c539a8d9270ba5a3f7d6e460606483fc2ab1eb61
|
|
# Soundfont used for MIDI music, matching what engine/build_deps.sh itself
|
|
# fetches (a free substitute for the Windows default GM soundfont).
|
|
ARG SOUNDFONT_URL=http://rancid.kapsi.fi/windows.sf2
|
|
# GLEW, for the Windows/MinGW cross-build only (engine/CMakeLists.txt's
|
|
# WIN32 branch - Windows' own opengl32.dll only exposes OpenGL 1.1, so
|
|
# anything newer needs GLEW's runtime extension loading; Linux instead
|
|
# gets modern prototypes straight from Mesa's headers, no loader needed -
|
|
# see engine/src/MacSrc/OpenGL.cc). Matches the version engine/'s own
|
|
# upstream Windows build script (build_win64.sh) used.
|
|
ARG GLEW_VERSION=2.1.0
|
|
# Gitea/GitHub Actions' JS-based actions (actions/checkout,
|
|
# actions/upload-artifact, ...) need a node binary in the container job's
|
|
# PATH - this image is otherwise pure C toolchain, so it isn't pulled in
|
|
# by anything else.
|
|
ARG NODE_VERSION=20.18.1
|
|
|
|
# Android layer, for the Quest APK build (Quest 2, 3, 3S, Pro - all
|
|
# arm64-v8a, see build-apk.sh). Same SDL2 major version as the desktop
|
|
# build above, but SDL2/SDL2_mixer are much newer releases here - unlike
|
|
# the desktop autotools build, Android needs their real CMake+NDK build
|
|
# support, which only landed in later releases. targetSdkVersion 29 (not
|
|
# compileSdk, which can and does stay newer) is deliberate: paired with
|
|
# requestLegacyExternalStorage in the manifest, it keeps /sdcard a plain,
|
|
# unrestricted shared folder instead of hitting Android 11+ scoped
|
|
# storage - this is keyed off the *app's* targetSdkVersion, not the
|
|
# device's own Android version, so it keeps working on newer Quest
|
|
# hardware/OS updates too, not just whatever's current today.
|
|
ARG ANDROID_SDL2_VERSION=2.28.5
|
|
ARG ANDROID_SDL2_MIXER_VERSION=2.8.0
|
|
ARG ANDROID_CMDLINE_TOOLS_VERSION=11076708
|
|
ARG ANDROID_PLATFORM_VERSION=29
|
|
# compileSdk in android/app/build.gradle - separate from the app's own
|
|
# targetSdkVersion (29, above): compileSdk is just which android.jar the
|
|
# app compiles against, and androidx.core needs a newer one than 29.
|
|
ARG ANDROID_COMPILE_SDK_VERSION=34
|
|
ARG ANDROID_BUILD_TOOLS_VERSION=34.0.0
|
|
ARG ANDROID_NDK_VERSION=26.1.10909125
|
|
ARG ANDROID_CMAKE_VERSION=3.22.1
|
|
# NDK 26 doesn't yet default to 16 KB-aligned ELF LOAD segments (that only
|
|
# became automatic in NDK 28+) - Google requires this for Play Store
|
|
# submissions targeting Android 15+ as of Nov 2025, and it's cheap/harmless
|
|
# to do regardless of Play Store status. Passed to every Android shared-lib
|
|
# CMake configure below, and to the engine's own build via
|
|
# android/app/build.gradle's externalNativeBuild.cmake.arguments.
|
|
ARG ANDROID_16KB_LDFLAGS="-Wl,-z,max-page-size=16384"
|
|
# GL4ES (https://github.com/ptitSeb/gl4es) - translates the engine's
|
|
# desktop-style immediate-mode OpenGL calls into real GLES/EGL calls, so
|
|
# engine/src/MacSrc/OpenGL.cc needs no immediate-mode rewrite on Android.
|
|
# Vendored directly into android/gl4es-src/ (currently tag v1.1.6, gl4es's
|
|
# latest release) rather than fetched at build time, same rationale as
|
|
# engine/: lets android/gl4es-patches/ instrument it directly (this is
|
|
# Android/GLES-only, with no desktop build depending on it, so unlike
|
|
# engine/ there's no shared tree to protect - see that patch's own comment
|
|
# for why this was needed, tracking down the OpenXR menu-quad texture bug).
|
|
# Re-vendoring a newer tag later: re-clone into android/gl4es-src/, then
|
|
# reapply/update the patches in android/gl4es-patches/.
|
|
# Unlike SDL2/SDL2_mixer/fluidsynth-lite/OpenXR below, gl4es is NOT
|
|
# prebuilt in this image - it's compiled from a scratch, patched copy as a
|
|
# CMake subdirectory of the engine's own native build (see
|
|
# build-image/prepare-android-project.sh and
|
|
# android/engine-patches/02-android-opengl-es.patch), so gl4es-patches/
|
|
# changes only need a normal Android Studio/gradlew rebuild, not a
|
|
# build-image rebuild.
|
|
# Khronos' own OpenXR loader (https://github.com/KhronosGroup/OpenXR-SDK) -
|
|
# the vendor-neutral loader, not Meta's redistributed copy, per this
|
|
# project's "favor OpenXR" rule (see README's Design principles). Only the
|
|
# loader is built (BUILD_LOADER=ON, everything else off) - the actual XR
|
|
# runtime implementation is resolved on-device by Horizon OS at load time,
|
|
# nothing else needs bundling. Verify this is still the latest release tag
|
|
# at https://github.com/KhronosGroup/OpenXR-SDK/releases when bumping.
|
|
ARG ANDROID_OPENXR_VERSION=1.1.42
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
# build-essential/cmake/make: engine/ itself (CMake) and SDL2/SDL2_mixer
|
|
# (autotools).
|
|
# git: fetches fluidsynth-lite; also used by engine/CMakeLists.txt's own
|
|
# `git describe` version string (harmless no-op if engine/ isn't a repo).
|
|
# curl/ca-certificates: fetches SDL2/SDL2_mixer tarballs and the soundfont.
|
|
# pkg-config: SDL2_mixer's configure and engine/CMakeLists.txt's
|
|
# pkg_check_modules() calls.
|
|
# gosu: docker-entrypoint.sh drops from root to a HOST_UID/GID user so
|
|
# build output isn't left root-owned on the bind-mounted repo.
|
|
# libgl1-mesa-dev/libglx-dev/libxext-dev/libx11-dev/libxrandr-dev/libxi-dev/
|
|
# libxfixes-dev/libxss-dev/libxinerama-dev/libxcursor-dev: SDL2's video
|
|
# backend (X11 + GL).
|
|
# libogg-dev/libvorbis-dev: SDL2_mixer's OGG Vorbis music decoder.
|
|
# libasound2-dev: engine/CMakeLists.txt's optional native ALSA MIDI output.
|
|
# openssh-client: the CI workflow's `sftp` publish step.
|
|
# openjdk-17-jdk-headless: Gradle/AGP's own minimum JDK for the APK build.
|
|
# unzip: extracts the Android cmdline-tools zip below.
|
|
# mingw-w64: the x86_64-w64-mingw32-{gcc,g++,windres,ar,...} cross
|
|
# toolchain for the Windows desktop build (see the "Windows cross-compile"
|
|
# section below). Ubuntu ships both a win32-thread-model and a
|
|
# posix-thread-model variant behind update-alternatives; the default
|
|
# (win32) is fine here since nothing in engine/ uses std::thread.
|
|
# zip: `make package-win`'s Windows release archive - a CI job's own
|
|
# `make package` runs inside this image as its container (see
|
|
# .gitea/workflows/build.yml), so it needs to be baked in here, not just
|
|
# available on a local dev machine's own host (see README).
|
|
#
|
|
# All apt installs deliberately live in this one RUN, first, so editing
|
|
# anything below it (in particular the Android cross-compile steps, the
|
|
# newest and least settled part of this file) never invalidates Docker's
|
|
# build cache for this layer - and vice versa, adding a package here only
|
|
# ever costs a rebuild of the (slow) layers below it, not a re-download
|
|
# of packages that didn't change.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
build-essential cmake make git curl ca-certificates pkg-config gosu \
|
|
libgl1-mesa-dev libglx-dev libxext-dev libx11-dev libxrandr-dev \
|
|
libxi-dev libxfixes-dev libxss-dev libxinerama-dev libxcursor-dev \
|
|
libogg-dev libvorbis-dev libasound2-dev openssh-client \
|
|
openjdk-17-jdk-headless unzip mingw-w64 zip \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
WORKDIR /opt/prebuilt
|
|
|
|
# SDL2, built the same way engine/build_deps.sh builds it (BUNDLED mode),
|
|
# just at image-build time instead of every game build.
|
|
RUN curl -sSLO "https://www.libsdl.org/release/SDL2-${SDL2_VERSION}.tar.gz" \
|
|
&& tar xf "SDL2-${SDL2_VERSION}.tar.gz" \
|
|
&& cd "SDL2-${SDL2_VERSION}" \
|
|
&& ./configure --prefix=/opt/prebuilt/built_sdl \
|
|
&& make -j"$(nproc)" \
|
|
&& make install \
|
|
&& cd .. && rm -rf "SDL2-${SDL2_VERSION}" "SDL2-${SDL2_VERSION}.tar.gz"
|
|
|
|
# SDL2_mixer, linked against the SDL2 build above via SDL2_CONFIG - same as
|
|
# engine/build_deps.sh's build_sdl_mixer().
|
|
RUN curl -sSLO "https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-${SDL2_MIXER_VERSION}.tar.gz" \
|
|
&& tar xf "SDL2_mixer-${SDL2_MIXER_VERSION}.tar.gz" \
|
|
&& cd "SDL2_mixer-${SDL2_MIXER_VERSION}" \
|
|
&& SDL2_CONFIG=/opt/prebuilt/built_sdl/bin/sdl2-config \
|
|
./configure --prefix=/opt/prebuilt/built_sdl_mixer \
|
|
&& make -j"$(nproc)" \
|
|
&& make install \
|
|
&& cd .. && rm -rf "SDL2_mixer-${SDL2_MIXER_VERSION}" "SDL2_mixer-${SDL2_MIXER_VERSION}.tar.gz"
|
|
|
|
# fluidsynth-lite: the stripped-down FluidSynth fork engine/CMakeLists.txt's
|
|
# BUNDLED FluidSynth mode expects at build_ext/fluidsynth-lite. Built
|
|
# in-source (its own CMake setup expects that), forcing a shared library
|
|
# the same way engine/build_deps.sh's sed does.
|
|
RUN git clone https://github.com/EtherTyper/fluidsynth-lite.git \
|
|
&& cd fluidsynth-lite \
|
|
&& git checkout "${FLUIDSYNTH_LITE_REF}" \
|
|
&& sed -i 's/DLL"\ off/DLL"\ on/' CMakeLists.txt \
|
|
&& cmake . \
|
|
&& cmake --build . -j"$(nproc)" \
|
|
&& rm -rf .git
|
|
|
|
# General MIDI soundfont for fluidsynth playback - engine/build_deps.sh
|
|
# fetches the same file and drops it into engine/res/. Shared by both the
|
|
# Linux and Windows builds below.
|
|
RUN mkdir -p soundfont \
|
|
&& curl -sSL -o soundfont/default.sf2 "${SOUNDFONT_URL}"
|
|
|
|
# CMake toolchain file for the Windows/MinGW cross-build below, reused at
|
|
# container-run time by build-image/build-engine-win.sh (see
|
|
# MINGW_TOOLCHAIN_FILE) to cross-compile engine/ itself the same way. GCC's
|
|
# runtime (libgcc/libstdc++) is linked statically so only the SDL2/
|
|
# SDL2_mixer/GLEW/fluidsynth-lite DLLs (plus libwinpthread, which isn't
|
|
# safe to static-link the same way) need shipping alongside systemshock.exe.
|
|
ENV MINGW_TOOLCHAIN_FILE=/opt/mingw-toolchain.cmake
|
|
RUN printf '%s\n' \
|
|
'set(CMAKE_SYSTEM_NAME Windows)' \
|
|
'set(CMAKE_SYSTEM_PROCESSOR x86_64)' \
|
|
'set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)' \
|
|
'set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)' \
|
|
'set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)' \
|
|
'set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)' \
|
|
'# LIBRARY/INCLUDE/PACKAGE deliberately left at CMake'"'"'s own' \
|
|
'# cross-compiling default (BOTH) - engine/CMakeLists.txt'"'"'s' \
|
|
'# BUNDLED SDL2/SDL2_mixer/FluidSynth find_library() calls point at' \
|
|
'# build_ext/ (outside this sysroot entirely), which ONLY would' \
|
|
'# refuse to search.' \
|
|
'set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)' \
|
|
'set(CMAKE_EXE_LINKER_FLAGS_INIT "-static-libgcc -static-libstdc++")' \
|
|
> "${MINGW_TOOLCHAIN_FILE}"
|
|
|
|
# SDL2 and SDL2_mixer for Windows: unlike the desktop build above, these
|
|
# are libsdl.org's own official prebuilt MinGW devel packages (headers +
|
|
# import libs + DLLs for x86_64-w64-mingw32), not built from source here -
|
|
# SDL2's autotools setup targets *nix; upstream ships MinGW builds
|
|
# pre-made instead, same as engine/'s own upstream Windows build script
|
|
# (build_win64.sh) uses. Same version pins as the Linux build above, so
|
|
# both desktop builds ship the same SDL2/SDL2_mixer release.
|
|
RUN curl -sSLO "https://www.libsdl.org/release/SDL2-devel-${SDL2_VERSION}-mingw.tar.gz" \
|
|
&& tar xf "SDL2-devel-${SDL2_VERSION}-mingw.tar.gz" \
|
|
&& mkdir -p /opt/prebuilt/win \
|
|
&& mv "SDL2-${SDL2_VERSION}/x86_64-w64-mingw32" /opt/prebuilt/win/sdl2 \
|
|
&& rm -rf "SDL2-${SDL2_VERSION}" "SDL2-devel-${SDL2_VERSION}-mingw.tar.gz"
|
|
|
|
RUN curl -sSLO "https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-devel-${SDL2_MIXER_VERSION}-mingw.tar.gz" \
|
|
&& tar xf "SDL2_mixer-devel-${SDL2_MIXER_VERSION}-mingw.tar.gz" --exclude=Xcode \
|
|
&& mv "SDL2_mixer-${SDL2_MIXER_VERSION}/x86_64-w64-mingw32" /opt/prebuilt/win/sdl2_mixer \
|
|
&& rm -rf "SDL2_mixer-${SDL2_MIXER_VERSION}" "SDL2_mixer-devel-${SDL2_MIXER_VERSION}-mingw.tar.gz"
|
|
|
|
# GLEW for Windows: compiled directly instead of via GLEW's own bundled
|
|
# cross-compile Makefile configs (config/Makefile.linux-mingw64 et al) -
|
|
# those pass raw `-soname`/`--out-implib` straight to whatever $(LD) is
|
|
# set to, which only works if LD is the real `ld` binary, not gcc-as-
|
|
# linker-driver (and that config also hardcodes a 32-bit `i686-w64-
|
|
# mingw32` host despite the "64" in its name) - simpler and more robust
|
|
# to just compile+link GLEW's one source file ourselves. Produces
|
|
# glew32.dll (to ship alongside systemshock.exe) and libglew32.dll.a (the
|
|
# MinGW import library engine/CMakeLists.txt's WIN32 branch links
|
|
# against).
|
|
RUN curl -sSL -o "glew-${GLEW_VERSION}.tgz" \
|
|
"https://sourceforge.net/projects/glew/files/glew/${GLEW_VERSION}/glew-${GLEW_VERSION}.tgz/download" \
|
|
&& tar xf "glew-${GLEW_VERSION}.tgz" \
|
|
&& cd "glew-${GLEW_VERSION}" \
|
|
&& mkdir -p /opt/prebuilt/win/glew/include/GL /opt/prebuilt/win/glew/lib \
|
|
&& x86_64-w64-mingw32-gcc -DGLEW_NO_GLU -O2 -Iinclude -c src/glew.c -o glew.o \
|
|
&& x86_64-w64-mingw32-gcc -shared \
|
|
-Wl,--out-implib,/opt/prebuilt/win/glew/lib/libglew32.dll.a \
|
|
-o /opt/prebuilt/win/glew/lib/glew32.dll \
|
|
glew.o -lopengl32 -lgdi32 -luser32 -lkernel32 \
|
|
&& cp include/GL/glew.h include/GL/wglew.h /opt/prebuilt/win/glew/include/GL/ \
|
|
&& cd .. && rm -rf "glew-${GLEW_VERSION}" "glew-${GLEW_VERSION}.tgz"
|
|
|
|
# fluidsynth-lite for Windows: same source/ref/DLL-mode patch as the
|
|
# desktop build above, cross-compiled via the MinGW toolchain file. WIN32
|
|
# skips fluidsynth-lite's own pthread dependency (see its CMakeLists.txt),
|
|
# so no libwinpthread linkage to worry about here.
|
|
RUN git clone https://github.com/EtherTyper/fluidsynth-lite.git fluidsynth-lite-win \
|
|
&& cd fluidsynth-lite-win \
|
|
&& git checkout "${FLUIDSYNTH_LITE_REF}" \
|
|
&& sed -i 's/DLL"\ off/DLL"\ on/' CMakeLists.txt \
|
|
&& rm -rf .git \
|
|
&& cd .. \
|
|
&& cmake -S fluidsynth-lite-win -B build-fluidsynth-win \
|
|
-DCMAKE_TOOLCHAIN_FILE="${MINGW_TOOLCHAIN_FILE}" \
|
|
&& cmake --build build-fluidsynth-win -j"$(nproc)" \
|
|
&& mkdir -p /opt/prebuilt/win/fluidsynth-lite/lib /opt/prebuilt/win/fluidsynth-lite/include \
|
|
&& cp build-fluidsynth-win/src/*.dll build-fluidsynth-win/src/*.dll.a \
|
|
/opt/prebuilt/win/fluidsynth-lite/lib/ \
|
|
&& cp -a fluidsynth-lite-win/include/. /opt/prebuilt/win/fluidsynth-lite/include/ \
|
|
&& cp build-fluidsynth-win/include/fluidsynth/version.h \
|
|
/opt/prebuilt/win/fluidsynth-lite/include/fluidsynth/version.h \
|
|
&& rm -rf fluidsynth-lite-win build-fluidsynth-win
|
|
|
|
# Node.js: needed only so Gitea/GitHub Actions' JS-based actions can run
|
|
# when this image is used as a CI job's container - see NODE_VERSION above.
|
|
RUN curl -sSL -o /tmp/node.tar.xz \
|
|
"https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \
|
|
&& tar -xJf /tmp/node.tar.xz -C /usr/local --strip-components=1 \
|
|
&& rm /tmp/node.tar.xz
|
|
|
|
# Android SDK/NDK: the cmdline-tools' own sdkmanager installs exactly the
|
|
# platform/build-tools/NDK/CMake versions the app/build.gradle below pins.
|
|
# gradlew (invoked by build-apk.sh) resolves its own pinned Gradle version
|
|
# itself - no Gradle binary is baked into this image. Unlike the manually
|
|
# cross-compiled SDL2/SDL2_mixer/fluidsynth-lite below, `./gradlew
|
|
# assembleDebug` still needs network access at build time for Gradle/AGP's
|
|
# own dependency resolution - an accepted, deliberate exception to this
|
|
# image's otherwise-offline build philosophy (see build-apk.sh).
|
|
ENV ANDROID_HOME=/opt/android-sdk \
|
|
ANDROID_SDK_ROOT=/opt/android-sdk
|
|
ENV PATH=${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${PATH}
|
|
|
|
RUN mkdir -p "${ANDROID_HOME}/cmdline-tools" \
|
|
&& curl -sSL -o /tmp/cmdline-tools.zip \
|
|
"https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_CMDLINE_TOOLS_VERSION}_latest.zip" \
|
|
&& unzip -q /tmp/cmdline-tools.zip -d "${ANDROID_HOME}/cmdline-tools" \
|
|
&& mv "${ANDROID_HOME}/cmdline-tools/cmdline-tools" "${ANDROID_HOME}/cmdline-tools/latest" \
|
|
&& rm /tmp/cmdline-tools.zip \
|
|
&& yes | sdkmanager --licenses >/dev/null \
|
|
&& sdkmanager --install \
|
|
"platform-tools" \
|
|
"platforms;android-${ANDROID_PLATFORM_VERSION}" \
|
|
"platforms;android-${ANDROID_COMPILE_SDK_VERSION}" \
|
|
"build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
|
|
"ndk;${ANDROID_NDK_VERSION}" \
|
|
"cmake;${ANDROID_CMAKE_VERSION}"
|
|
|
|
ENV ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}
|
|
ENV ANDROID_NDK_TOOLCHAIN=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake
|
|
|
|
# SDL2, SDL2_mixer, and fluidsynth-lite, cross-compiled for arm64-v8a (the
|
|
# Quest's only ABI, across Quest 2/3/3S/Pro) via the NDK's CMake toolchain file, each installed
|
|
# to its own prefix under /opt/prebuilt/android/ - mirrors the desktop
|
|
# build_ext/built_sdl / built_sdl_mixer layout, just for Android. Shipped
|
|
# in the APK as separate .so's (see build-apk.sh), loaded in that order by
|
|
# QuestShockActivity.getLibraries() before the game's own libmain.so.
|
|
ARG ANDROID_ABI=arm64-v8a
|
|
|
|
RUN curl -sSLO "https://www.libsdl.org/release/SDL2-${ANDROID_SDL2_VERSION}.tar.gz" \
|
|
&& tar xf "SDL2-${ANDROID_SDL2_VERSION}.tar.gz" \
|
|
&& cmake -S "SDL2-${ANDROID_SDL2_VERSION}" -B build-sdl2-android \
|
|
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_TOOLCHAIN}" \
|
|
-DANDROID_ABI="${ANDROID_ABI}" -DANDROID_PLATFORM="android-${ANDROID_PLATFORM_VERSION}" \
|
|
-DCMAKE_INSTALL_PREFIX=/opt/prebuilt/android/sdl2 -DBUILD_SHARED_LIBS=ON \
|
|
-DSDL_STATIC=OFF \
|
|
-DCMAKE_SHARED_LINKER_FLAGS="${ANDROID_16KB_LDFLAGS}" \
|
|
&& cmake --build build-sdl2-android -j"$(nproc)" \
|
|
&& cmake --install build-sdl2-android \
|
|
&& rm -rf "SDL2-${ANDROID_SDL2_VERSION}" "SDL2-${ANDROID_SDL2_VERSION}.tar.gz" build-sdl2-android
|
|
|
|
# All optional codecs disabled: Shockolate only ever calls
|
|
# Mix_LoadWAV_RW/Mix_HookMusic (confirmed by grep - it feeds fluidsynth's
|
|
# own PCM output through Mix_HookMusic, and never loads OGG/MOD/FLAC/MP3
|
|
# game data), so plain WAVE support (always built in, no extra
|
|
# dependency) is all that's needed - avoiding SDL2_mixer's vendored
|
|
# third-party codec libraries entirely.
|
|
RUN curl -sSLO "https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-${ANDROID_SDL2_MIXER_VERSION}.tar.gz" \
|
|
&& tar xf "SDL2_mixer-${ANDROID_SDL2_MIXER_VERSION}.tar.gz" \
|
|
&& cmake -S "SDL2_mixer-${ANDROID_SDL2_MIXER_VERSION}" -B build-sdl2mixer-android \
|
|
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_TOOLCHAIN}" \
|
|
-DANDROID_ABI="${ANDROID_ABI}" -DANDROID_PLATFORM="android-${ANDROID_PLATFORM_VERSION}" \
|
|
-DCMAKE_PREFIX_PATH=/opt/prebuilt/android/sdl2 \
|
|
-DCMAKE_FIND_ROOT_PATH=/opt/prebuilt/android/sdl2 \
|
|
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH \
|
|
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \
|
|
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH \
|
|
-DCMAKE_INSTALL_PREFIX=/opt/prebuilt/android/sdl2_mixer -DBUILD_SHARED_LIBS=ON \
|
|
-DSDL2MIXER_VENDORED=OFF -DSDL2MIXER_SAMPLES=OFF -DSDL2MIXER_CMD=OFF \
|
|
-DSDL2MIXER_FLAC=OFF -DSDL2MIXER_GME=OFF -DSDL2MIXER_MOD=OFF \
|
|
-DSDL2MIXER_MP3=OFF -DSDL2MIXER_MIDI=OFF -DSDL2MIXER_OPUS=OFF -DSDL2MIXER_VORBIS=OFF \
|
|
-DSDL2MIXER_WAVPACK=OFF \
|
|
-DCMAKE_SHARED_LINKER_FLAGS="${ANDROID_16KB_LDFLAGS}" \
|
|
&& cmake --build build-sdl2mixer-android -j"$(nproc)" \
|
|
&& cmake --install build-sdl2mixer-android \
|
|
&& rm -rf "SDL2_mixer-${ANDROID_SDL2_MIXER_VERSION}" "SDL2_mixer-${ANDROID_SDL2_MIXER_VERSION}.tar.gz" build-sdl2mixer-android
|
|
|
|
RUN git clone https://github.com/EtherTyper/fluidsynth-lite.git fluidsynth-lite-android \
|
|
&& cd fluidsynth-lite-android \
|
|
&& git checkout "${FLUIDSYNTH_LITE_REF}" \
|
|
&& sed -i 's/DLL"\ off/DLL"\ on/' CMakeLists.txt \
|
|
&& sed -i 's/-Wall -Werror -std=gnu11/-Wall -std=gnu11/' CMakeLists.txt \
|
|
&& sed -i 's/set ( LIBFLUID_LIBS m pthread )/set ( LIBFLUID_LIBS m )/' CMakeLists.txt \
|
|
&& rm -rf .git \
|
|
&& cd .. \
|
|
&& cmake -S fluidsynth-lite-android -B build-fluidsynth-android \
|
|
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_TOOLCHAIN}" \
|
|
-DANDROID_ABI="${ANDROID_ABI}" -DANDROID_PLATFORM="android-${ANDROID_PLATFORM_VERSION}" \
|
|
-DCMAKE_SHARED_LINKER_FLAGS="${ANDROID_16KB_LDFLAGS}" \
|
|
&& cmake --build build-fluidsynth-android -j"$(nproc)" \
|
|
&& mkdir -p /opt/prebuilt/android/fluidsynth-lite/lib /opt/prebuilt/android/fluidsynth-lite/include \
|
|
&& cp -a build-fluidsynth-android/src/libfluidsynth.so* /opt/prebuilt/android/fluidsynth-lite/lib/ \
|
|
&& cp -a fluidsynth-lite-android/include/. /opt/prebuilt/android/fluidsynth-lite/include/ \
|
|
# version.h is generated from version.h.in at configure time - fine on
|
|
# the desktop build (in-source, so it lands right back in the source
|
|
# tree), but this is an out-of-source build, so it only exists under
|
|
# build-fluidsynth-android/ and must be copied in separately.
|
|
&& cp -a build-fluidsynth-android/include/fluidsynth/version.h \
|
|
/opt/prebuilt/android/fluidsynth-lite/include/fluidsynth/version.h \
|
|
&& rm -rf fluidsynth-lite-android build-fluidsynth-android
|
|
|
|
# OpenXR loader, for the immersive VR mode (android/app/src/main/cpp/
|
|
# xr_session.c and friends) - see android/engine-patches/
|
|
# 11-android-openxr-cmake.patch for how the engine links it.
|
|
RUN git clone --branch "release-${ANDROID_OPENXR_VERSION}" --depth 1 \
|
|
https://github.com/KhronosGroup/OpenXR-SDK.git openxr-sdk-android \
|
|
&& rm -rf openxr-sdk-android/.git \
|
|
&& cmake -S openxr-sdk-android -B build-openxr-android \
|
|
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_TOOLCHAIN}" \
|
|
-DANDROID_ABI="${ANDROID_ABI}" -DANDROID_PLATFORM="android-${ANDROID_PLATFORM_VERSION}" \
|
|
-DCMAKE_INSTALL_PREFIX=/opt/prebuilt/android/openxr \
|
|
-DBUILD_LOADER=ON -DBUILD_TESTS=OFF -DBUILD_API_LAYERS=OFF \
|
|
-DBUILD_CONFORMANCE_TESTS=OFF -DBUILD_WITH_SYSTEM_JSONCPP=OFF \
|
|
-DDYNAMIC_LOADER=ON \
|
|
-DCMAKE_SHARED_LINKER_FLAGS="${ANDROID_16KB_LDFLAGS}" \
|
|
&& cmake --build build-openxr-android -j"$(nproc)" --target openxr_loader \
|
|
&& cmake --install build-openxr-android \
|
|
&& mkdir -p /opt/prebuilt/android/openxr/include \
|
|
&& cp -a openxr-sdk-android/include/. /opt/prebuilt/android/openxr/include/ \
|
|
&& rm -rf openxr-sdk-android build-openxr-android
|
|
|
|
COPY build-image/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
|
COPY build-image/build-engine.sh /usr/local/bin/build-engine.sh
|
|
# 755, not +x: the entrypoint drops to a `builder` user matching the
|
|
# *host's* UID/GID (see docker-entrypoint.sh), which is never in these
|
|
# root-owned files' group, so it needs the image's own explicit
|
|
# world-read+execute here - `chmod +x` alone only adds execute bits on
|
|
# top of whatever "other" permissions the source file happened to have
|
|
# (which depends on the host's umask at checkout, e.g. a restrictive
|
|
# 0007 umask yields unreadable-by-other files, which then round-trip
|
|
# into the image and cause a Permission denied at container run time).
|
|
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh /usr/local/bin/build-engine.sh
|
|
|
|
# Marks a shell as already running inside this image (with every engine
|
|
# build dependency prebuilt above) - lets the Makefile's `engine` target
|
|
# compile directly instead of shelling out to ./run-image.sh's `docker
|
|
# run`, which matters for CI jobs that already run inside this image
|
|
# (nested docker-in-docker isn't available there).
|
|
ENV QUESTSHOCK_BUILD_IMAGE=1
|
|
|
|
WORKDIR /workspace
|
|
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
|
CMD ["/usr/local/bin/build-engine.sh"]
|