# 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 # 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 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. 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 \ && 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/. RUN mkdir -p soundfont \ && curl -sSL -o soundfont/default.sf2 "${SOUNDFONT_URL}" # 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 COPY build-image/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh COPY build-image/build-engine.sh /usr/local/bin/build-engine.sh RUN chmod +x /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"]