build: add linux builds (#984)

This commit is contained in:
Marcin Kurczewski 2023-09-20 14:00:42 +02:00 committed by GitHub
parent 0df2faa6b5
commit 2e685dd1ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 347 additions and 126 deletions

View file

@ -4,8 +4,8 @@ on:
- workflow_dispatch
jobs:
publish_docker_image:
name: Build Docker toolchain
publish_docker_image_win:
name: Build Windows Docker toolchain
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
@ -20,7 +20,28 @@ jobs:
path: .
fetch-depth: 0
- name: Build Docker image
- name: Build Docker image (Windows)
run: |
docker build -t "rrdash/tomb1main:latest" . -f docker/game/Dockerfile
docker build -t "rrdash/tomb1main:latest" . -f docker/game/win/Dockerfile
docker push "rrdash/tomb1main:latest"
publish_docker_image_linux:
name: Build Linux Docker toolchain
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Checkout code
uses: actions/checkout@v2
with:
path: .
fetch-depth: 0
- name: Build Docker image (Linux)
run: |
docker build -t "rrdash/tomb1main-linux:latest" . -f docker/game/linux/Dockerfile
docker push "rrdash/tomb1main-linux:latest"

View file

@ -36,7 +36,7 @@ jobs:
publish_release:
name: Create a GitHub release
runs-on: ubuntu-latest
needs: [build_game, build_installer]
needs: [build_game_win, build_installer]
steps:
- name: Checkout code
uses: actions/checkout@v3
@ -48,7 +48,13 @@ jobs:
uses: actions/download-artifact@v1
with:
path: artifacts/
name: game_all
name: game-win-all
- name: Download built game asset
uses: actions/download-artifact@v1
with:
path: artifacts/
name: game-linux-all
- name: Download built installer asset
uses: actions/download-artifact@v1
@ -62,7 +68,8 @@ jobs:
- name: Rename assets
run: |
mv artifacts/game.zip artifacts/Tomb1Main-${{ steps.get_version.outputs.VERSION }}.zip
mv artifacts/game-win.zip artifacts/Tomb1Main-${{ steps.get_version.outputs.VERSION }}-Windows.zip
mv artifacts/game-linux.zip artifacts/Tomb1Main-${{ steps.get_version.outputs.VERSION }}-Linux.zip
mv artifacts/Tomb1Main_Installer.exe artifacts/Tomb1Main-${{ steps.get_version.outputs.VERSION }}-Installer.exe
- name: Generate Changelog
@ -84,7 +91,8 @@ jobs:
prerelease: ${{ inputs.prerelease }}
fail_on_unmatched_files: true
files: |
artifacts/Tomb1Main-${{ steps.get_version.outputs.VERSION }}.zip
artifacts/Tomb1Main-${{ steps.get_version.outputs.VERSION }}-Windows.zip
artifacts/Tomb1Main-${{ steps.get_version.outputs.VERSION }}-Linux.zip
artifacts/Tomb1Main-${{ steps.get_version.outputs.VERSION }}-Installer.exe
build_configurator:
@ -114,8 +122,8 @@ jobs:
name: configtool
path: tools/config/out/Tomb1Main_ConfigTool.exe
build_game:
name: Build the game
build_game_win:
name: Build the game (Windows)
runs-on: ubuntu-latest
steps:
- name: Checkout code
@ -134,18 +142,18 @@ jobs:
run: |
make clean release
mkdir out/
cp build/*.exe out/
cp build/win/*.exe out/
cp -r bin/* out/
- name: Upload the artifact
uses: actions/upload-artifact@v1
with:
name: game
name: game-win
path: out/
package_game:
name: Package the game
needs: [build_game, build_configurator]
package_game_win:
name: Package the game (Windows)
needs: [build_game_win, build_configurator]
runs-on: ubuntu-latest
steps:
- name: Download built config tool assets
@ -158,7 +166,7 @@ jobs:
uses: actions/download-artifact@v1
with:
path: artifacts/
name: game
name: game-win
- name: Install dependencies
run: |
@ -169,17 +177,74 @@ jobs:
run: |
mkdir out
cd artifacts
7z a ../out/game.zip *
7z a ../out/game-win.zip *
- name: Upload the artifact
uses: actions/upload-artifact@v1
with:
name: game_all
path: out/game.zip
name: game-win-all
path: out/game-win.zip
build_game_linux:
name: Build the game (Linux)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
path: .
fetch-depth: 0
- name: Install dependencies
run: |
echo "$GITHUB_CONTEXT"
sudo apt-get update
sudo apt-get install -y make moby-engine moby-cli
- name: Build the game
run: |
make clean release-linux
mkdir out/
cp build/linux/Tomb1Main out/
cp -r bin/* out/
- name: Upload the artifact
uses: actions/upload-artifact@v1
with:
name: game-linux
path: out/
package_game_linux:
name: Package the game (Linux)
needs: [build_game_linux]
runs-on: ubuntu-latest
steps:
- name: Download built game assets
uses: actions/download-artifact@v1
with:
path: artifacts/
name: game-linux
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y make p7zip-full
- name: Package the game
run: |
mkdir out
cd artifacts
7z a ../out/game-linux.zip *
- name: Upload the artifact
uses: actions/upload-artifact@v1
with:
name: game-linux-all
path: out/game-linux.zip
build_installer:
name: Build the installer
needs: [package_game]
needs: [package_game_win]
runs-on: windows-latest # https://github.com/dotnet/runtime/issues/3828
steps:
- name: Checkout code
@ -192,7 +257,7 @@ jobs:
uses: actions/download-artifact@v1
with:
path: artifacts/
name: game_all
name: game-win-all
- name: Setup dependencies
uses: actions/setup-dotnet@v2
@ -201,7 +266,7 @@ jobs:
- name: Build
run: |
cp artifacts/game.zip tools/installer/Installer/Resources/release.zip
cp artifacts/game-win.zip tools/installer/Installer/Resources/release.zip
cd tools/installer
dotnet restore
dotnet publish -c Release -o out

View file

@ -1,4 +1,5 @@
## [Unreleased](https://github.com/rr-/Tomb1Main/compare/stable...develop) - ××××-××-××
- added Linux builds and toolchain
## [2.16](https://github.com/rr-/Tomb1Main/compare/2.15.3...2.16) - 2023-09-20
- added a new rendering mode called "framebuffer" that lets the game to run at lower resolutions (#114)

View file

@ -7,12 +7,23 @@ define build
mkdir -p build
docker run --rm \
--user $(HOST_USER_UID):$(HOST_USER_GID) \
--entrypoint /app/docker/game/entrypoint.sh \
--entrypoint /app/docker/game-win/entrypoint.sh \
-e TARGET="$(TARGET)" \
-v $(CWD):/app/ \
rrdash/tomb1main:latest
endef
define build-linux
$(eval TARGET := $(1))
mkdir -p build
docker run --rm \
--user $(HOST_USER_UID):$(HOST_USER_GID) \
--entrypoint /app/docker/game-linux/entrypoint.sh \
-e TARGET="$(TARGET)" \
-v $(CWD):/app/ \
rrdash/tomb1main-linux:latest
endef
debug:
$(call build,debug)
@ -22,6 +33,15 @@ debugopt:
release:
$(call build,release)
debug-linux:
$(call build-linux,debug)
debugopt-linux:
$(call build-linux,debugoptimized)
release-linux:
$(call build-linux,release)
clean:
-find build/ -type f -delete
-find build/ -mindepth 1 -empty -type d -delete
@ -32,18 +52,6 @@ imports:
lint:
bash -c 'shopt -s globstar; clang-format -i **/*.c **/*.h'
test_base:
cp build/*.exe test/
test_bin:
rsync -r bin/ test/
test: build test_base
WINEARCH=win32 MESA_GL_VERSION_OVERRIDE=3.3 wine test/Tomb1Main.exe
test_gold: build test_base
WINEARCH=win32 MESA_GL_VERSION_OVERRIDE=3.3 wine test/Tomb1Main.exe -gold
installer:
docker build . -f docker/installer/Dockerfile -t rrdash/tomb1main_installer
docker run --rm \
@ -60,4 +68,4 @@ config:
-v $(CWD):/app/ \
rrdash/tomb1main_config
.PHONY: debug debugopt release clean imports lint test_base test_bin test test_gold installer config
.PHONY: debug debugopt release clean imports lint installer config

View file

@ -418,6 +418,7 @@ Not all options are turned on by default. Refer to `Tomb1Main_ConfigTool.exe` fo
- added per-level customizable fog distance
#### Miscellaneous
- added Linux builds
- added .jpeg/.png screenshots
- added an option to pause sound in the inventory screen
- added ability to skip FMVs with the Action key
@ -454,33 +455,9 @@ Not all options are turned on by default. Refer to `Tomb1Main_ConfigTool.exe` fo
4. **Can I play this on Mac, Linux, Android...?**
We'd like to eventually have only SDL dependency.
## Road map
Note: this section may be subject to change.
- [x] Reverse engineer the main game module
- [x] Integrate the glrage patch
- [x] Replace the proprietary music player with libavcodec and SDL
- [x] Replace the proprietary FMV player with libavcodec and SDL
- [x] Break off TombATI, ship our own .EXE rather than a .DLL
- [x] Add an installer
- [x] Add a config tool
- [ ] Work on cross platform builds
- [x] Port DirectSound to libavcodec and SDL
- [x] Port WinMM to libavcodec and SDL
- [x] Port DirectInput to SDL
- [ ] Replace wgl_ext.h with cross platform variant
- [ ] Remove HWND and HINSTANCE usages
- [ ] ...
- [ ] Test for performance and crash resilience
- [ ] 3.0
- [ ] Work on data injection and other features
- [x] Add Lara's braid to each level
- [x] Fix texture/face issues
- [x] Fix floor data issues
- [ ] ...
Currently supported platforms include Windows and Linux. In the future, it
might be possible to run the game on Macs as well contributions are
welcome!
## License

View file

@ -0,0 +1,125 @@
# Tomb1Main building toolchain for Linux.
#
# This is a multi-stage Docker image. It is designed to keep the final image
# size low. Each stage builds an external dependency. The final stage takes the
# artifacts (binaries, includes etc.) from previous stages and installs all the
# tools necessary to build Tomb1Main.
FROM ubuntu:latest as base
# don't prompt during potential installation/update of tzinfo
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Warsaw
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y \
git \
make
# libav
FROM base as libav
RUN apt-get install -y \
nasm \
gcc \
zlib1g-dev
RUN git clone \
--depth 1 \
--branch "n4.4.1" \
https://github.com/FFmpeg/FFmpeg
RUN cd FFmpeg \
&& ./configure \
--arch=x86 \
--prefix=/ext/ \
--enable-gpl \
--enable-decoder=pcx \
--enable-decoder=png \
--enable-decoder=gif \
--enable-decoder=mjpeg \
--enable-decoder=mpeg4 \
--enable-decoder=mdec \
--enable-decoder=h264 \
--enable-decoder=h264_qsv \
--enable-decoder=libopenh264 \
--enable-decoder=png \
--enable-demuxer=mov \
--enable-demuxer=avi \
--enable-demuxer=h264 \
--enable-demuxer=str \
--enable-demuxer=image2 \
--enable-zlib \
--enable-static \
--enable-small \
--disable-debug \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-network \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--disable-asm \
&& make -j 4 \
&& make install
# SDL
FROM base as sdl
RUN git clone https://github.com/libsdl-org/SDL -b SDL2
RUN apt-get install -y \
libgl1-mesa-dev \
libglu1-mesa-dev \
libpulse-dev \
automake \
gcc \
libxext-dev
RUN cd SDL \
&& aclocal -I acinclude \
&& autoconf \
&& mkdir sdl_build \
&& cd sdl_build \
&& ../configure \
--prefix=/ext/ \
--enable-shared \
--enable-static \
&& make -j 4 \
&& make install
# Tomb1Main
FROM base
# set the build dir - actual files are mounted with a Docker volume
RUN mkdir /app
WORKDIR /app
# package dependencies
RUN apt-get install -y \
zlib1g-dev \
libgl1-mesa-dev
# tooling dependencies
# configure pkgconfig manually
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=967969
ENV PKG_CONFIG_LIBDIR=/ext/lib/
ENV PKG_CONFIG_PATH=/ext/lib/pkgconfig/
RUN apt-get install -y \
pkg-config \
upx \
git \
python3-pip \
&& python3 -m pip install \
pyjson5 \
meson \
ninja
# manually built dependencies
COPY --from=libav /ext/ /ext/
COPY --from=sdl /ext/ /ext/
ENTRYPOINT ["/app/docker/game-linux/entrypoint-linux.sh"]

18
docker/game-linux/entrypoint.sh Executable file
View file

@ -0,0 +1,18 @@
#!/bin/sh
set -x
set -e
export CFLAGS=-DDOCKER_BUILD
if [ ! -f /app/build/linux/build.ninja ]; then
meson --buildtype "$TARGET" /app/build/linux/ --pkg-config-path=$PKG_CONFIG_PATH
fi
cd /app/build/linux; meson compile
if [ "$TARGET" = release ]; then
for file in Tomb1Main; do
upx -t "$file" || ( strip "$file" && upx "$file" )
done
fi

17
docker/game-win/entrypoint.sh Executable file
View file

@ -0,0 +1,17 @@
#!/bin/sh
set -x
set -e
export CFLAGS=-DDOCKER_BUILD
if [ ! -f /app/build/win/build.ninja ]; then
meson --buildtype "$TARGET" /app/build/win/ --cross /app/docker/game-win/meson_linux_mingw32.txt --pkg-config-path=$PKG_CONFIG_PATH
fi
cd /app/build/win; meson compile
if [ "$TARGET" = release ]; then
for file in *.exe; do
upx -t "$file" || ( i686-w64-mingw32-strip "$file" && upx "$file" )
done
fi

View file

@ -1,17 +0,0 @@
#!/bin/sh
set -x
set -e
export CFLAGS=-DDOCKER_BUILD
if [ ! -f /app/build/build.ninja ]; then
meson --buildtype "$TARGET" /app/build/ --cross /app/docker/game/meson_linux_mingw32.txt --pkg-config-path=$PKG_CONFIG_PATH
fi
cd /app/build; meson compile
if [ "$TARGET" = release ]; then
for file in *.exe; do
upx -t "$file" || ( i686-w64-mingw32-strip "$file" && upx "$file" )
done
fi

View file

@ -21,7 +21,11 @@ build_opts = [
c_opts = []
add_project_arguments(build_opts + c_opts, language: 'c')
dep_opengl32 = c_compiler.find_library('opengl32')
if host_machine.system() == 'windows'
dep_opengl32 = c_compiler.find_library('opengl32')
else
dep_opengl32 = dependency('GL')
endif
dep_avcodec = dependency('libavcodec', static: true)
dep_avformat = dependency('libavformat', static: true)
@ -35,43 +39,45 @@ dep_sdl2 = dependency('SDL2', static: true)
resources = []
python3 = find_program('python3', required: true)
git = find_program('git', required: true)
if python3.found()
version = custom_target('version',
output: ['version.txt'],
command: [python3, meson.source_root() + '/tools/generate_version', '-o', '@OUTPUT0@'],
build_by_default: true,
build_always_stale: true
)
init = custom_target(
'fake_init',
depends: [version],
input: [version[0]],
output: ['init.c'],
command: [python3, meson.source_root() + '/tools/generate_init', '--version-file', '@INPUT@', '-o', '@OUTPUT0@'],
build_by_default: true,
)
version_rc = custom_target(
'fake_version',
depends: [version],
input: [version[0]],
output: ['version.rc'],
command: [python3, meson.source_root() + '/tools/generate_rcfile', '--version-file', '@INPUT@', '-o', '@OUTPUT0@'],
build_by_default: true,
)
icon_rc = custom_target(
'fake_icon',
input: [version[0]],
output: ['icon.rc'],
command: [python3, meson.source_root() + '/tools/generate_rcfile', '--version-file', '@INPUT@', '-o', '@OUTPUT0@'],
)
if host_machine.system() == 'windows'
windows = import('windows')
resources = [
windows.compile_resources(version_rc),
windows.compile_resources(icon_rc),
]
endif
version = custom_target('version',
output: ['version.txt'],
command: [python3, meson.source_root() + '/tools/generate_version', '-o', '@OUTPUT0@'],
build_by_default: true,
build_always_stale: true
)
init = custom_target(
'fake_init',
depends: [version],
input: [version[0]],
output: ['init.c'],
command: [python3, meson.source_root() + '/tools/generate_init', '--version-file', '@INPUT@', '-o', '@OUTPUT0@'],
build_by_default: true,
)
version_rc = custom_target(
'fake_version',
depends: [version],
input: [version[0]],
output: ['version.rc'],
command: [python3, meson.source_root() + '/tools/generate_rcfile', '--version-file', '@INPUT@', '-o', '@OUTPUT0@'],
build_by_default: true,
)
icon_rc = custom_target(
'fake_icon',
input: [version[0]],
output: ['icon.rc'],
command: [python3, meson.source_root() + '/tools/generate_rcfile', '--version-file', '@INPUT@', '-o', '@OUTPUT0@'],
)
if host_machine.system() == 'windows'
windows = import('windows')
resources = [
windows.compile_resources(version_rc),
windows.compile_resources(icon_rc),
]
link_args = ['-static']
else
link_args = []
endif
sources = [
@ -263,14 +269,14 @@ sources = [
]
dependencies = [
dep_avcodec,
dep_avformat,
dep_avutil,
dep_opengl32,
dep_sdl2,
dep_swresample,
dep_swscale,
]
dep_avcodec,
dep_avformat,
dep_avutil,
dep_opengl32,
dep_sdl2,
dep_swresample,
dep_swscale,
]
executable(
'Tomb1Main',
@ -278,6 +284,6 @@ executable(
name_prefix: '',
include_directories: ['src/'],
dependencies: dependencies,
link_args: ['-static'],
link_args: link_args,
gui_app: true,
)