├── .gitignore ├── .github ├── dependabot.yml └── workflows │ └── appimage.yml ├── .env ├── docker-compose.yml ├── AppRun ├── README.md ├── LICENSE └── make-appimage.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /*tar.xz* 2 | /tools/ 3 | /linuxdeploy-plugin-gtk.sh 4 | /*.AppImage* 5 | /0ad-* 6 | /minisign*linux.tar.gz* 7 | /out 8 | /premake*tar.gz 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "docker" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # These variables can be overridden by exporting them from the 2 | # command line when running `docker compose` 3 | # 4 | # Your numeric uid and gid 5 | HOSTUID= 6 | HOSTGID= 7 | 8 | # When run from the root of your project directory, this will be 9 | # the location in the container 10 | WORKSPACE="/workspace" 11 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | build: 3 | environment: 4 | HOSTUID: ${HOSTUID} 5 | HOSTGID: ${HOSTGID} 6 | VERSION: "${VERSION:-0.27.1}" 7 | WORKSPACE: ${WORKSPACE} 8 | CC: "${CC:-gcc}" 9 | CXX: "${CXX:-g++}" 10 | image: andy5995/linuxdeploy:v3-jammy 11 | platform: ${PLATFORM} 12 | volumes: 13 | - ${PWD}:${WORKSPACE} 14 | working_dir: ${WORKSPACE} 15 | 16 | # Note that SCRIPT is not used by the container, therefore 17 | # is not included within the 'environment' section above 18 | # 19 | # Absolute path or Relative to workspace 20 | # e.g. $WORKSPACE/path/to/script 21 | command: "${SCRIPT:-./make-appimage.sh}" 22 | -------------------------------------------------------------------------------- /AppRun: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | # The purpose of this custom AppRun script is 4 | # to allow symlinking the AppImage and invoking 5 | # the corresponding binary depending on which 6 | # symlink was used to invoke the AppImage 7 | # make sure errors in sourced scripts will cause this script to stop 8 | set -e 9 | 10 | HERE="$(readlink -f "$(dirname "$0")")" 11 | 12 | BINARY_NAME=${BINARY_NAME:-"pyrogenesis"} 13 | 14 | echo "To invoke the Actor editor:" 15 | echo "BINARY_NAME=ActorEditor $0" 16 | echo "" 17 | 18 | if [ "$BINARY_NAME" = "pyrogenesis" ] || [ "$BINARY_NAME" = "0ad" ]; then 19 | exec "$HERE/usr/bin/pyrogenesis" "$@" 20 | elif [ "$BINARY_NAME" = "ActorEditor" ]; then 21 | exec "$HERE/usr/bin/ActorEditor" "$@" 22 | else 23 | exec "$HERE/usr/bin/pyrogenesis" "$@" 24 | fi 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 0ad appimage 2 | 3 | Unofficial [0ad](https://play0ad.com/) 4 | [AppImage](https://appimage.org/) (built from official sources and 5 | data) 6 | 7 | Click on the [releases 8 | link](https://github.com/0ad-matters/0ad-appimage/releases) to view 9 | available appimages. 10 | 11 | To invoke the `ActorEditor`: 12 | 13 | BINARY_NAME=ActorEditor 14 | 15 | ## Updating 16 | 17 | The AppImage is updateable (if you downloaded it after February 1st, 2025) 18 | with 19 | [appimageupdatetool](https://github.com/AppImageCommunity/AppImageUpdate). If 20 | it's not available from your distro, you can download the tool as an AppImage 21 | from the repo (linked above) or by using [AM, a command line AppImage package 22 | manager](https://github.com/ivan-hc/AM). 23 | 24 | ## Build locally 25 | 26 | You can build the appimage locally if you have docker installed. While in the 27 | repo root, to build the latest stable version: 28 | 29 | export HOSTUID=$(id -u) HOSTGID=$(id -g) 30 | docker compose -f ./docker-compose.yml run --rm build 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Andy Alt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/appimage.yml: -------------------------------------------------------------------------------- 1 | name: Release Appimage 2 | concurrency: 3 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} 4 | cancel-in-progress: true 5 | 6 | on: 7 | workflow_dispatch: 8 | push: 9 | branches: [ "trunk" ] 10 | paths-ignore: 11 | - '.gitignore' 12 | - 'LICENSE' 13 | - 'README.md' 14 | pull_request: 15 | branches: [ "trunk" ] 16 | paths-ignore: 17 | - '.gitignore' 18 | - 'LICENSE' 19 | - 'README.md' 20 | 21 | jobs: 22 | # Label of the container job 23 | build-appimage: 24 | strategy: 25 | fail-fast: false 26 | matrix: 27 | os: 28 | - ubuntu-24.04-arm 29 | - ubuntu-24.04 30 | 31 | runs-on: ${{ matrix.os }} 32 | env: 33 | VERSION: 0.27.1 34 | MINISIGN_KEY: RWTWLbO12+ig3lUExIor3xd6DdZaYFEozn8Bu8nIzY3ImuRYQszIQyyy 35 | steps: 36 | - uses: actions/checkout@v5 37 | 38 | - name: Build AppImage 39 | run: | 40 | export HOSTUID=$(id -u) HOSTGID=$(id -g) 41 | docker compose -f ./docker-compose.yml run --rm build 42 | 43 | - name: Release AppImage 44 | if: ${{ github.ref == 'refs/heads/trunk' }} 45 | uses: ncipollo/release-action@v1 46 | with: 47 | name: 0ad-${{ env.VERSION }} AppImage 48 | allowUpdates: True 49 | prerelease: ${{ contains(env.VERSION, 'rc') }} 50 | artifacts: ./out/0ad*.AppImage* 51 | token: ${{ secrets.GITHUB_TOKEN }} 52 | omitNameDuringUpdate: True 53 | omitBodyDuringUpdate: True 54 | tag: v${{ env.VERSION }} 55 | replacesArtifacts: true 56 | - name: Upload Artifacts 57 | if: ${{ github.ref != 'refs/heads/trunk' }} 58 | uses: actions/upload-artifact@v5 59 | with: 60 | name: AppImage-${{ matrix.os }} 61 | path: ./out/0ad*.AppImage* 62 | -------------------------------------------------------------------------------- /make-appimage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | if [ -z "$DOCKER_BUILD" ]; then 6 | echo "This script is only meant to be used with the linuxdeploy build" 7 | echo "helper container." 8 | echo "See the 0ad-appimage README for details." 9 | exit 1 10 | fi 11 | 12 | if [ -z "$VERSION" ]; then 13 | echo "VERSION must be set" 14 | exit 1 15 | fi 16 | 17 | if [[ "$WORKSPACE" != /* ]]; then 18 | echo "The workspace path must be absolute" 19 | exit 1 20 | fi 21 | test -d "$WORKSPACE" 22 | 23 | SOURCE_ROOT="$WORKSPACE/0ad-$VERSION" 24 | if [[ "$SOURCE_ROOT" != /* ]]; then 25 | echo "The source root path must be absolute" 26 | exit 1 27 | fi 28 | 29 | APPDIR=${APPDIR:-"/tmp/$USER-AppDir"} 30 | if [ -d "$APPDIR" ]; then 31 | rm -rf "$APPDIR" 32 | else 33 | mkdir -v -p "$APPDIR" 34 | fi 35 | 36 | env 37 | export -p 38 | 39 | URI="https://releases.wildfiregames.com" 40 | 41 | cd $WORKSPACE 42 | if [ ! -e "AppRun" ]; then 43 | echo "You must be in the same directory where the AppRun file resides" 44 | exit 1 45 | fi 46 | 47 | cd "$WORKSPACE" 48 | 49 | sudo DEBIAN_FRONTEND=noninteractive -i sh -c "apt update && apt -y upgrade && 50 | apt install -y 51 | cargo 52 | curl 53 | $CC 54 | libboost-dev 55 | libboost-filesystem-dev 56 | libboost-system-dev 57 | libcurl4-gnutls-dev 58 | libenet-dev 59 | libfmt-dev 60 | libfreetype6-dev 61 | libgloox-dev 62 | libicu-dev 63 | libminiupnpc-dev 64 | libogg-dev 65 | libopenal-dev 66 | libpng-dev 67 | libsdl2-dev 68 | libsodium-dev 69 | libvorbis-dev 70 | libwxgtk3.0-gtk3-dev 71 | libxml2-dev 72 | llvm 73 | m4 74 | patchelf 75 | python3 76 | rustc 77 | zlib1g-dev 78 | " 79 | 80 | PREMAKE="premake-5.0.0-beta4-linux.tar.gz" 81 | if [ ! -f "$PREMAKE" ]; then 82 | wget https://github.com/premake/premake-core/releases/download/v5.0.0-beta4/$PREMAKE 83 | tar -xvf "$PREMAKE" 84 | sudo mv premake5 /usr/bin 85 | fi 86 | 87 | source=0ad-$VERSION-unix-build.tar.xz 88 | source_sum=$source.sha1sum 89 | for file in $source $source_sum; do 90 | if [ ! -f "$file" ]; then 91 | curl -LO "$URI/$file" 92 | fi 93 | done 94 | sha1sum -c $source_sum 95 | 96 | if [ ! -r "$SOURCE_ROOT/source/main.cpp" ]; then 97 | tar -xJf $source 98 | fi 99 | 100 | cd "$SOURCE_ROOT/libraries" 101 | ./build-source-libs.sh -j$(nproc) 102 | 103 | cd "$SOURCE_ROOT/build/workspaces" 104 | ./update-workspaces.sh \ 105 | --without-pch \ 106 | --with-lto \ 107 | -j$(nproc) 108 | make config=release -C gcc -j$(nproc) 109 | 110 | cd $WORKSPACE 111 | data=0ad-$VERSION-unix-data.tar.xz 112 | data_sum=$data.sha1sum 113 | for file in $data $data_sum; do 114 | if [ ! -f "$file" ]; then 115 | curl -LO "$URI/$file" 116 | fi 117 | done 118 | sha1sum -c $data_sum 119 | 120 | cd "$WORKSPACE" 121 | if [ ! -f "$SOURCE_ROOT/binaries/data/config/default.cfg" ]; then 122 | echo "Extracting data" 123 | tar -xJf $data 124 | fi 125 | 126 | # name: prepare AppDir 127 | 128 | #if [ -n "${URI##*/rc*}" ] && [ ! -r $URI/$data.minisig ]; then 129 | #curl -LO $URI/$data.minisig 130 | #fi 131 | 132 | #$MINISIGN_PATH -Vm $data -P $MINISIGN_KEY 133 | 134 | cd "$SOURCE_ROOT" 135 | install -s binaries/system/pyrogenesis -Dt $APPDIR/usr/bin 136 | install -s binaries/system/ActorEditor -Dt $APPDIR/usr/bin 137 | cd $APPDIR/usr/bin 138 | ln -s pyrogenesis 0ad 139 | for lib in libmozjs78-ps-release.so \ 140 | libnvcore.so \ 141 | libnvimage.so \ 142 | libnvmath.so \ 143 | libnvtt.so 144 | do 145 | patchelf --set-rpath $lib:$SOURCE_ROOT/binaries/system pyrogenesis 146 | done 147 | patchelf --set-rpath libthai.so.0:$APPDIR/usr/lib ActorEditor 148 | patchelf --set-rpath libAtlasUI.so:$SOURCE_ROOT/binaries/system ActorEditor 149 | # Note that binaries/system{libmoz*.so, libnv*.so, libAtlasUI.so} will be copied into 150 | # the $APPDIR folder automatically when linuxdeploy is run below. 151 | cd $SOURCE_ROOT 152 | install binaries/system/libCollada.so -Dt $APPDIR/usr/lib 153 | install build/resources/0ad.appdata.xml -Dt $APPDIR/usr/share/metainfo 154 | install build/resources/0ad.png -Dt $APPDIR/usr/share/pixmaps 155 | mkdir -p "$APPDIR/usr/data/config" 156 | cp -a binaries/data/config/default.cfg $APPDIR/usr/data/config 157 | cp -a binaries/data/l10n $APPDIR/usr/data 158 | cp -a binaries/data/tools $APPDIR/usr/data # for Atlas 159 | mkdir -p $APPDIR/usr/data/mods 160 | cp -a binaries/data/mods/mod $APPDIR/usr/data/mods 161 | 162 | cd $SOURCE_ROOT 163 | cp -a binaries/data/mods/public $APPDIR/usr/data/mods 164 | 165 | cd "$WORKSPACE" 166 | 167 | # Set up output directory 168 | OUT_DIR="$WORKSPACE/out" 169 | if [ ! -d "$OUT_DIR" ]; then 170 | mkdir "$OUT_DIR" 171 | fi 172 | cd "$OUT_DIR" 173 | 174 | # Set LinuxDeploy output version 175 | export LINUXDEPLOY_OUTPUT_VERSION="$VERSION" 176 | 177 | # Create the image 178 | if [ -z "$ACTION_WORKSPACE" ]; then 179 | export DEPLOY_GTK_VERSION=3 180 | ARCH=$(uname -m) 181 | # Variable used by gtk plugin 182 | linuxdeploy \ 183 | -d $SOURCE_ROOT/build/resources/0ad.desktop \ 184 | --icon-file=$SOURCE_ROOT/build/resources/0ad.png \ 185 | --icon-filename=0ad \ 186 | --executable $APPDIR/usr/bin/pyrogenesis \ 187 | --library=/usr/lib/$ARCH-linux-gnu/libthai.so.0 \ 188 | --custom-apprun=$WORKSPACE/AppRun \ 189 | --appdir $APPDIR \ 190 | --plugin gtk 191 | fi 192 | 193 | OUT_APPIMAGE="0ad-$VERSION-$ARCH.AppImage" 194 | 195 | REPO="0ad-appimage" 196 | TAG="latest" 197 | GITHUB_REPOSITORY_OWNER="${GITHUB_REPOSITORY_OWNER:-0ad-matters}" 198 | UPINFO="gh-releases-zsync|$GITHUB_REPOSITORY_OWNER|$REPO|$TAG|*$ARCH.AppImage.zsync" 199 | 200 | appimagetool --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 20 \ 201 | -u "$UPINFO" \ 202 | "$APPDIR" "$OUT_APPIMAGE" 203 | 204 | sha1sum $OUT_APPIMAGE > "$OUT_APPIMAGE.sha1sum" 205 | cat "$OUT_APPIMAGE.sha1sum" 206 | 207 | exit 0 208 | --------------------------------------------------------------------------------