# Assembles dist/ (Linux) and dist-win/ (Windows, cross-compiled via # MinGW) - self-contained, runnable copies of System Shock - from the # compiled engine (built via Docker, see build-image.sh/run-image.sh) and # the game assets extracted from a purchased copy (see # res/assets/extract_assets.sh). Building the engine needs the build-image # (./build-image.sh, once); everything else here is plain file copying. # `dist-linux`/`dist-win` build just one platform; plain `dist` builds # both. # # `make package` instead builds redistributable archives (a .tar.gz for # Linux, a .zip for Windows) that omit the proprietary game assets # entirely (see res/assets/GET_ASSETS.txt, which they ship in their # place) - this is what CI publishes. Same dist-linux/dist-win/(both) # split via package-linux/package-win/package. DIST_DIR := dist DIST_WIN_DIR := dist-win ENGINE_OUT := engine/.build-output ENGINE_OUT_WIN := engine/.build-output-win ASSETS_DIR := res/assets/ss_ee BUILD_DIR := build ARCH := $(shell uname -m) .PHONY: all dist dist-linux dist-win build-image engine engine-win assets \ package package-linux package-win apk android-studio clean all: dist # Builds the Docker build-image itself. Only needed once, or after # build-image/Dockerfile changes. build-image: ./build-image.sh # Compiles engine/ (the vendored Shockolate snapshot) - offline, since # every dependency it needs was already baked into the build-image. # Always re-run so `make dist`/`make package` reflect the current engine/ # source, same as a fresh checkout would. # # If we're already running inside the build-image (QUESTSHOCK_BUILD_IMAGE, # set by its Dockerfile - true for a CI job using it as its container, # which has no nested docker available), compile directly; otherwise # shell out to ./run-image.sh, which docker-runs the image against this # checkout. engine: @if [ -n "$$QUESTSHOCK_BUILD_IMAGE" ]; then \ bash build-image/build-engine.sh; \ else \ ./run-image.sh; \ fi # Cross-compiles engine/ for Windows via MinGW - see build-engine-win.sh # for why this can't share build-engine.sh's engine/build_ext/ (a scratch # copy is used instead). Same QUESTSHOCK_BUILD_IMAGE detection as `engine`. engine-win: @if [ -n "$$QUESTSHOCK_BUILD_IMAGE" ]; then \ bash build-image/build-engine-win.sh; \ else \ ./run-image.sh bash build-image/build-engine-win.sh; \ fi # Fails with a pointer to extract_assets.sh if the purchased game assets # haven't been extracted yet. assets: @if [ ! -d "$(ASSETS_DIR)/data" ] || [ ! -d "$(ASSETS_DIR)/sound" ]; then \ echo "PREFLIGHT FAIL: $(ASSETS_DIR) not found - run res/assets/extract_assets.sh first" >&2; \ echo "(see res/assets/extract_assets.sh for how to get the installer from gog.com)" >&2; \ exit 1; \ fi # Builds both platforms. `dist-linux`/`dist-win` build just one. dist: dist-linux dist-win dist-linux: engine assets @echo "== Assembling $(DIST_DIR) ==" rm -rf "$(DIST_DIR)/systemshock" "$(DIST_DIR)/lib" "$(DIST_DIR)/res" \ "$(DIST_DIR)/shaders" "$(DIST_DIR)/run.sh" mkdir -p "$(DIST_DIR)/lib" "$(DIST_DIR)/res/data" "$(DIST_DIR)/res/sound" cp "$(ENGINE_OUT)/systemshock" "$(DIST_DIR)/" cp -a "$(ENGINE_OUT)/lib/." "$(DIST_DIR)/lib/" cp "$(ENGINE_OUT)/soundfont.sf2" "$(DIST_DIR)/res/" cp -a engine/shaders "$(DIST_DIR)/shaders" cp -a "$(ASSETS_DIR)/data/." "$(DIST_DIR)/res/data/" cp -a "$(ASSETS_DIR)/sound/." "$(DIST_DIR)/res/sound/" cp res/run.sh "$(DIST_DIR)/run.sh" chmod +x "$(DIST_DIR)/run.sh" @echo "== Done - run $(DIST_DIR)/run.sh to play ==" # Windows counterpart of dist-linux. Unlike dist/, the DLLs sit flat # alongside systemshock.exe instead of in a lib/ subdirectory - Windows' # default DLL search order already checks the executable's own directory # first, so (unlike run.sh's LD_LIBRARY_PATH) run.bat needs no extra # wiring for that. dist-win: engine-win assets @echo "== Assembling $(DIST_WIN_DIR) ==" rm -rf "$(DIST_WIN_DIR)" mkdir -p "$(DIST_WIN_DIR)/res/data" "$(DIST_WIN_DIR)/res/sound" cp "$(ENGINE_OUT_WIN)/systemshock.exe" "$(ENGINE_OUT_WIN)"/*.dll "$(DIST_WIN_DIR)/" cp "$(ENGINE_OUT_WIN)/soundfont.sf2" "$(DIST_WIN_DIR)/res/" cp -a engine/shaders "$(DIST_WIN_DIR)/shaders" cp -a "$(ASSETS_DIR)/data/." "$(DIST_WIN_DIR)/res/data/" cp -a "$(ASSETS_DIR)/sound/." "$(DIST_WIN_DIR)/res/sound/" cp res/run.bat "$(DIST_WIN_DIR)/run.bat" @echo "== Done - run $(DIST_WIN_DIR)/run.bat (or systemshock.exe) to play ==" # Builds both platforms' redistributable archives. `package-linux`/ # `package-win` build just one. package: package-linux package-win # Builds a versioned, redistributable Linux release tarball at # dist/shockolate--linux-.tar.gz - everything needed to # run except the proprietary game assets (res/GET_ASSETS.txt explains how # to get those instead of shipping res/data/, res/sound/). Version # defaults to the current git tag (vX.Y.Z, tag prefix stripped) - push a # tag to drive a release. Override with `make package VERSION=1.2.3`, or # just run it untagged for a local dev build (gets a 0.0.0-dev+ # placeholder version, with a warning). package-linux: engine @git config --global --add safe.directory "$$(pwd)" 2>/dev/null || true @V="$$(VERSION="$(VERSION)" ./build-image/version.sh)"; \ PKG_NAME="shockolate-$$V-linux-$(ARCH)"; \ PKG_STAGE="$(BUILD_DIR)/package/$$PKG_NAME"; \ echo "Packaging $$PKG_NAME"; \ rm -rf "$$PKG_STAGE"; \ mkdir -p "$$PKG_STAGE/lib" "$$PKG_STAGE/res"; \ cp "$(ENGINE_OUT)/systemshock" "$$PKG_STAGE/"; \ cp -a "$(ENGINE_OUT)/lib/." "$$PKG_STAGE/lib/"; \ cp -a engine/shaders "$$PKG_STAGE/shaders"; \ cp "$(ENGINE_OUT)/soundfont.sf2" "$$PKG_STAGE/res/"; \ cp res/assets/GET_ASSETS.txt "$$PKG_STAGE/res/GET_ASSETS.txt"; \ cp res/run.sh "$$PKG_STAGE/run.sh"; \ chmod +x "$$PKG_STAGE/run.sh"; \ cp LICENSE "$$PKG_STAGE/LICENSE"; \ cp engine/LICENSE "$$PKG_STAGE/LICENSE.Shockolate"; \ cp NOTICE.txt "$$PKG_STAGE/NOTICE.txt"; \ mkdir -p "$(DIST_DIR)"; \ tar -czf "$(DIST_DIR)/$$PKG_NAME.tar.gz" -C "$(BUILD_DIR)/package" "$$PKG_NAME"; \ rm -rf "$(BUILD_DIR)/package"; \ echo "Wrote $(DIST_DIR)/$$PKG_NAME.tar.gz" # Windows counterpart of package-linux: dist/shockolate--windows- # x86_64.zip. Same versioning (build-image/version.sh) and VERSION= # override. Needs `zip` on whatever host runs `make package-win` itself # (unlike engine-win's own build, packaging isn't run inside the # build-image) - see README's Desktop build prerequisites. package-win: engine-win @git config --global --add safe.directory "$$(pwd)" 2>/dev/null || true @command -v zip >/dev/null 2>&1 || { echo "PREFLIGHT FAIL: zip not found in PATH" >&2; exit 1; } @V="$$(VERSION="$(VERSION)" ./build-image/version.sh)"; \ PKG_NAME="shockolate-$$V-windows-x86_64"; \ PKG_STAGE="$(BUILD_DIR)/package/$$PKG_NAME"; \ echo "Packaging $$PKG_NAME"; \ rm -rf "$$PKG_STAGE"; \ mkdir -p "$$PKG_STAGE/res"; \ cp "$(ENGINE_OUT_WIN)/systemshock.exe" "$(ENGINE_OUT_WIN)"/*.dll "$$PKG_STAGE/"; \ cp -a engine/shaders "$$PKG_STAGE/shaders"; \ cp "$(ENGINE_OUT_WIN)/soundfont.sf2" "$$PKG_STAGE/res/"; \ cp res/assets/GET_ASSETS.txt "$$PKG_STAGE/res/GET_ASSETS.txt"; \ cp res/run.bat "$$PKG_STAGE/run.bat"; \ cp LICENSE "$$PKG_STAGE/LICENSE"; \ cp engine/LICENSE "$$PKG_STAGE/LICENSE.Shockolate"; \ cp NOTICE.txt "$$PKG_STAGE/NOTICE.txt"; \ mkdir -p "$(DIST_DIR)"; \ (cd "$(BUILD_DIR)/package" && zip -rq "$(CURDIR)/$(DIST_DIR)/$$PKG_NAME.zip" "$$PKG_NAME"); \ rm -rf "$(BUILD_DIR)/package"; \ echo "Wrote $(DIST_DIR)/$$PKG_NAME.zip" # Builds the Quest APK (see build-image/build-apk.sh and # android/engine-patches/ - engine/ itself is never modified; a patch is # applied to a scratch copy at build time instead). Same # QUESTSHOCK_BUILD_IMAGE detection as `engine`. Unlike every other target # here, this needs network access at build time (Gradle/AGP's own # dependency resolution) - see build-image/Dockerfile. apk: @if [ -n "$$QUESTSHOCK_BUILD_IMAGE" ]; then \ bash build-image/build-apk.sh; \ else \ ./run-image.sh bash build-image/build-apk.sh; \ fi # Stages a scratch, patched copy of engine/ and android/gl4es-src/, plus # the Android SDL2/SDL2_mixer/fluidsynth-lite/openxr prebuilts, with # host-resolvable paths (writes android/engine.properties) so Android # Studio can compile and deploy android/ natively - see README's "5.2. # Building natively in Android Studio". `make apk` doesn't need this; it # stages the same things itself inside the build-image. Re-run after # `make clean` (which deletes android/engine.properties) or after # changing engine/, android/engine-patches/, android/gl4es-src/, # android/gl4es-patches/, or the prebuilt-library versions in # build-image/Dockerfile - Android Studio's own Gradle build already # does this automatically via its stageEngine task, so this is mainly # useful for first-time setup or confirming staging succeeded on its own. android-studio: ./run-image.sh bash build-image/prepare-android-project.sh --host-paths clean: rm -rf "$(DIST_DIR)" "$(DIST_WIN_DIR)" "$(BUILD_DIR)" "$(ENGINE_OUT)" "$(ENGINE_OUT_WIN)" \ engine/build_ext engine/CMakeCache.txt engine/CMakeFiles \ engine/cmake_install.cmake engine/Makefile engine/systemshock \ engine/src/Libraries/CMakeFiles \ android/engine.properties android/app/src/main/assets android/app/src/main/jniLibs \ android/app/build android/.gradle android/app/.cxx