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:
+113
-3
@@ -18,6 +18,13 @@ 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
|
||||
@@ -99,6 +106,15 @@ ENV DEBIAN_FRONTEND=noninteractive
|
||||
# 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
|
||||
@@ -111,7 +127,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
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 \
|
||||
openjdk-17-jdk-headless unzip mingw-w64 zip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /opt/prebuilt
|
||||
@@ -150,10 +166,96 @@ RUN git clone https://github.com/EtherTyper/fluidsynth-lite.git \
|
||||
&& rm -rf .git
|
||||
|
||||
# General MIDI soundfont for fluidsynth playback - engine/build_deps.sh
|
||||
# fetches the same file and drops it into engine/res/.
|
||||
# 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 \
|
||||
@@ -283,7 +385,15 @@ RUN git clone --branch "release-${ANDROID_OPENXR_VERSION}" --depth 1 \
|
||||
|
||||
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
|
||||
# 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
|
||||
|
||||
@@ -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"
|
||||
@@ -22,9 +22,28 @@ cd "$ENGINE_DIR"
|
||||
echo "== Wiring up prebuilt SDL2/SDL2_mixer/fluidsynth-lite from the image =="
|
||||
rm -rf build_ext
|
||||
mkdir -p build_ext
|
||||
cp -a /opt/prebuilt/built_sdl build_ext/
|
||||
cp -a /opt/prebuilt/built_sdl_mixer build_ext/
|
||||
cp -a /opt/prebuilt/fluidsynth-lite build_ext/
|
||||
|
||||
# Some filesystems the repo might be checked out on (e.g. a VirtualBox
|
||||
# vboxsf shared folder) refuse to create symlinks at all ("Operation not
|
||||
# permitted"), which plain `cp -a` needs for SDL2/SDL2_mixer's
|
||||
# libFoo.so -> libFoo.so.N -> libFoo.so.N.M dev-symlink chain. Detect
|
||||
# that up front, once, and copy real file content instead of recreating
|
||||
# links if so, rather than failing partway through. `-a` implies
|
||||
# --preserve=all (which includes hard-link relationships between files,
|
||||
# not just symlinks - SDL2's install hard-links the two most-specific
|
||||
# version files together), so --no-preserve=links is needed alongside
|
||||
# --dereference to avoid that too.
|
||||
CP_FLAGS=(-a)
|
||||
if ! ln -s test-target build_ext/.symlink-test 2>/dev/null; then
|
||||
echo "(destination filesystem doesn't support symlinks - copying real file content instead)"
|
||||
CP_FLAGS=(-a --dereference --no-preserve=links)
|
||||
else
|
||||
rm -f build_ext/.symlink-test
|
||||
fi
|
||||
|
||||
cp "${CP_FLAGS[@]}" /opt/prebuilt/built_sdl build_ext/
|
||||
cp "${CP_FLAGS[@]}" /opt/prebuilt/built_sdl_mixer build_ext/
|
||||
cp "${CP_FLAGS[@]}" /opt/prebuilt/fluidsynth-lite build_ext/
|
||||
|
||||
echo "== Configuring (CMake, BUNDLED SDL2/SDL2_mixer/FluidSynth) =="
|
||||
rm -f CMakeCache.txt
|
||||
@@ -38,7 +57,7 @@ rm -rf "$OUT_DIR"
|
||||
mkdir -p "$OUT_DIR/lib"
|
||||
cp systemshock "$OUT_DIR/"
|
||||
find build_ext/built_sdl/lib build_ext/built_sdl_mixer/lib build_ext/fluidsynth-lite/src \
|
||||
-name '*.so*' -not -name '*.la' -exec cp -a {} "$OUT_DIR/lib/" \;
|
||||
-name '*.so*' -not -name '*.la' -exec cp "${CP_FLAGS[@]}" {} "$OUT_DIR/lib/" \;
|
||||
cp /opt/prebuilt/soundfont/default.sf2 "$OUT_DIR/soundfont.sf2"
|
||||
|
||||
echo "== Done =="
|
||||
|
||||
@@ -11,4 +11,17 @@ USER_GID="${HOST_GID:-1000}"
|
||||
groupadd -g "$USER_GID" builder 2>/dev/null || true
|
||||
useradd -u "$USER_UID" -g "$USER_GID" -m -s /bin/bash builder 2>/dev/null || true
|
||||
|
||||
# /workspace (the bind-mounted repo) may actually be owned by a group the
|
||||
# host user only has via *supplementary* membership rather than their
|
||||
# primary GID above - e.g. a VirtualBox vboxsf shared folder, which shows
|
||||
# up as root:vboxsf on the host and would otherwise be inaccessible to
|
||||
# `builder` here (falls through to "other", which vboxsf's default mode
|
||||
# leaves with no permissions at all). Join whatever group actually owns
|
||||
# /workspace too, if it differs.
|
||||
WORKSPACE_GID="$(stat -c %g /workspace 2>/dev/null || true)"
|
||||
if [ -n "$WORKSPACE_GID" ] && [ "$WORKSPACE_GID" != "$USER_GID" ]; then
|
||||
groupadd -g "$WORKSPACE_GID" workspace 2>/dev/null || true
|
||||
usermod -aG "$WORKSPACE_GID" builder 2>/dev/null || true
|
||||
fi
|
||||
|
||||
exec gosu builder "$@"
|
||||
|
||||
Reference in New Issue
Block a user