Skip to content

Commit

Permalink
aarch64-linux-gnu cross-compilation
Browse files Browse the repository at this point in the history
Allows one to easily cross-compile for aarch64 on a Debian/Ubuntu host.
Also adds a GitHub Action for it.
  • Loading branch information
glebm committed Apr 1, 2023
1 parent 13e38c2 commit dd31034
Show file tree
Hide file tree
Showing 9 changed files with 212 additions and 5 deletions.
79 changes: 79 additions & 0 deletions .github/workflows/Linux_aarch64.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Linux AArch64

on:
push:
branches:
- master
paths-ignore:
- '*.md'
pull_request:
types: [opened, synchronize]
paths-ignore:
- '*.md'
release:
types: [published]
paths-ignore:
- '*.md'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Create Build Environment
run: |
# Work around the somewhat broken packages in the GitHub Actions Ubuntu 20.04 image.
# https://github.com/actions/runner-images/issues/4620#issuecomment-981333260
sudo apt-get -y install --allow-downgrades libpcre2-8-0=10.34-7
Packaging/nix/debian-cross-aarch64-prep.sh
- name: Build
working-directory: ${{github.workspace}}
shell: bash
env:
CMAKE_BUILD_TYPE: ${{github.event_name == 'release' && 'Release' || 'RelWithDebInfo'}}
# We set DEVILUTIONX_SYSTEM_LIBFMT=OFF because its soversion changes frequently.
run: |
cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=../CMake/platforms/aarch64-linux-gnu.toolchain.cmake \
-DCMAKE_BUILD_TYPE=${{env.CMAKE_BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=/usr -DCPACK=ON \
-DDEVILUTIONX_SYSTEM_LIBFMT=OFF && \
cmake --build build -j $(getconf _NPROCESSORS_ONLN) --target package
- name: Package
run: Packaging/nix/LinuxReleasePackaging.sh && mv devilutionx.tar.xz devilutionx-aarch64.tar.xz

# AppImage cross-packaging is not implemented yet.
# - name: Package AppImage
# run: Packaging/nix/AppImage.sh && mv devilutionx.appimage devilutionx-aarch64.appimage

- name: Upload Package
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v2
with:
name: devilutionx-aarch64.tar.xz
path: devilutionx-aarch64.tar.xz

# AppImage cross-packaging is not implemented yet.
# - name: Upload AppImage
# if: ${{ !env.ACT }}
# uses: actions/upload-artifact@v2
# with:
# name: devilutionx-aarch64.appimage
# path: devilutionx-aarch64.appimage

- name: Update Release
if: ${{ github.event_name == 'release' && !env.ACT }}
uses: svenstaro/upload-release-action@v2
with:
file: devilutionx-aarch64.*
file_glob: true
overwrite: true
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ comparer-config.toml
# Extra files in the source distribution (see make_src_dist.py)
/dist/

*.appimage
*.AppImage

# ELF object file, shared library and object archive.
*.o
*.so
Expand Down
1 change: 1 addition & 0 deletions CMake/platforms/aarch64-linux-gnu-pkg-config
18 changes: 18 additions & 0 deletions CMake/platforms/aarch64-linux-gnu.toolchain.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(CMAKE_C_COMPILER "/usr/bin/aarch64-linux-gnu-gcc")
set(CMAKE_CXX_COMPILER "/usr/bin/aarch64-linux-gnu-g++")

set(CMAKE_FIND_ROOT_PATH "/usr/aarch64-linux-gnu;/usr")
set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu)

set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/aarch64-linux-gnu-pkg-config" CACHE STRING "Path to pkg-config")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE arm64)
50 changes: 50 additions & 0 deletions CMake/platforms/debian-cross-pkg-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/sh
# pkg-config wrapper for cross-building
# Sets pkg-config search path to search multiarch and historical cross-compiling paths.

# https://gist.github.com/doug65536/ea9c52f9a65a655a2fd5cc4997e8443b

# If the user has already set PKG_CONFIG_LIBDIR, believe it (even if empty):
# it's documented to be an override
if [ x"${PKG_CONFIG_LIBDIR+set}" = x ]; then
# GNU triplet for the compiler, e.g. i486-linux-gnu for Debian i386,
# i686-linux-gnu for Ubuntu i386
basename="`basename "$0"`"
triplet="${basename%-pkg-config}"
# Normalized multiarch path if any, e.g. i386-linux-gnu for i386
multiarch="`dpkg-architecture -t"${triplet}" -qDEB_HOST_MULTIARCH 2>/dev/null`"
# Native multiarch path
native_multiarch="$(cat /usr/lib/pkg-config.multiarch)"

# This can be used for native builds as well, in that case, just exec pkg-config "$@" directly.
if [ "$native_multiarch" = "$multiarch" ]; then
exec pkg-config "$@"
fi

PKG_CONFIG_LIBDIR="/usr/local/${triplet}/lib/pkgconfig"
# For a native build we would also want to append /usr/local/lib/pkgconfig
# at this point; but this is a cross-building script, so don't
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/local/share/pkgconfig"

if [ -n "$multiarch" ]; then
PKG_CONFIG_LIBDIR="/usr/local/lib/${multiarch}/pkgconfig:$PKG_CONFIG_LIBDIR"
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/lib/${multiarch}/pkgconfig"
fi

PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/${triplet}/lib/pkgconfig"
# For a native build we would also want to append /usr/lib/pkgconfig
# at this point; but this is a cross-building script, so don't
# If you want to allow use of un-multiarched -dev packages for crossing
# (at the risk of finding build-arch stuff you didn't want, if not in a clean chroot)
# Uncomment the next line:
# PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/lib/pkgconfig"
# ... but on Ubuntu we rely cross-building with non-multiarch libraries:
if dpkg-vendor --derives-from Ubuntu; then
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/lib/pkgconfig"
fi
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/share/pkgconfig"

export PKG_CONFIG_LIBDIR
fi

exec pkg-config "$@"
23 changes: 18 additions & 5 deletions Packaging/nix/AppImage.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
make install -Cbuild DESTDIR=AppDir
mv build/AppDir/usr/share/diasurgical/devilutionx/devilutionx.mpq build/AppDir/usr/bin/devilutionx.mpq
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage -N
chmod +x linuxdeploy-x86_64.AppImage
./linuxdeploy-x86_64.AppImage --appimage-extract-and-run --appdir=build/AppDir --custom-apprun=Packaging/nix/AppRun -d Packaging/nix/devilutionx.desktop -o appimage
#!/usr/bin/env bash
set -euo pipefail
set -x

BUILD_DIR="${1-build}"
cmake --install "$BUILD_DIR" --prefix "${BUILD_DIR}/AppDir/usr"
mv "$BUILD_DIR"/AppDir/usr/share/diasurgical/devilutionx/devilutionx.mpq "$BUILD_DIR"/AppDir/usr/bin/devilutionx.mpq

APPIMAGE_BUILDER="${APPIMAGE_BUILDER:-linuxdeploy-x86_64.AppImage}"
if ! which "$APPIMAGE_BUILDER"; then
if ! [[ -f linuxdeploy-x86_64.AppImage ]]; then
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage -N
chmod +x linuxdeploy-x86_64.AppImage
fi
APPIMAGE_BUILDER=./linuxdeploy-x86_64.AppImage
fi
"$APPIMAGE_BUILDER" --appimage-extract-and-run --appdir="$BUILD_DIR"/AppDir --custom-apprun=Packaging/nix/AppRun -d Packaging/nix/devilutionx.desktop -o appimage

mv DevilutionX*.AppImage devilutionx.appimage
24 changes: 24 additions & 0 deletions Packaging/nix/debian-cross-aarch64-prep.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -euo pipefail
set -x

FLAVOR="$(lsb_release -sc)"

if dpkg-vendor --derives-from Ubuntu; then
sudo tee /etc/apt/sources.list.d/arm64.list <<LIST
deb [arch=arm64] http://ports.ubuntu.com/ ${FLAVOR} main restricted
deb [arch=arm64] http://ports.ubuntu.com/ ${FLAVOR}-updates main restricted
deb [arch=arm64] http://ports.ubuntu.com/ ${FLAVOR} universe
deb [arch=arm64] http://ports.ubuntu.com/ ${FLAVOR}-updates universe
deb [arch=arm64] http://ports.ubuntu.com/ ${FLAVOR} multiverse
deb [arch=arm64] http://ports.ubuntu.com/ ${FLAVOR}-updates multiverse
deb [arch=arm64] http://ports.ubuntu.com/ ${FLAVOR}-backports main restricted universe multiverse
LIST
sudo sed -i 's/deb http/deb [arch=amd64,i386] http/' /etc/apt/sources.list
fi

sudo dpkg --add-architecture arm64
sudo apt-get update
sudo apt-get install -y cmake git smpq gettext crossbuild-essential-arm64 \
libsdl2-dev:arm64 libsdl2-image-dev:arm64 libsodium-dev:arm64 \
libsimpleini-dev:arm64 libpng-dev:arm64 libbz2-dev:arm64 libfmt-dev:arm64
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ If you want to help test the latest development stage of the next version (make

[![Linux x86](https://github.com/diasurgical/devilutionX/actions/workflows/Linux_x86.yml/badge.svg)](https://github.com/diasurgical/devilutionX/actions/workflows/Linux_x86.yml?query=branch%3Amaster)
[![Linux x86-64 SDL1](https://github.com/diasurgical/devilutionX/actions/workflows/Linux_x86_64_SDL1.yml/badge.svg)](https://github.com/diasurgical/devilutionX/actions/workflows/Linux_x86_64_SDL1.yml?query=branch%3Amaster)
[![Linux aarch64](https://github.com/diasurgical/devilutionX/actions/workflows/Linux_aarch64.yml/badge.svg)](https://github.com/diasurgical/devilutionX/actions/workflows/Linux_aarch64.yml?query=branch%3Amaster)
[![MacOSX](https://github.com/diasurgical/devilutionX/actions/workflows/MacOSX.yml/badge.svg)](https://github.com/diasurgical/devilutionX/actions/workflows/MacOSX.yml?query=branch%3Amaster)
[![Windows x64](https://github.com/diasurgical/devilutionX/actions/workflows/Windows_MSVC_x64.yml/badge.svg)](https://github.com/diasurgical/devilutionX/actions/workflows/Windows_MSVC_x64.yml?query=branch%3Amaster)
[![Windows MinGW x64](https://github.com/diasurgical/devilutionX/actions/workflows/Windows_MinGW_x64.yml/badge.svg)](https://github.com/diasurgical/devilutionX/actions/workflows/Windows_MinGW_x64.yml?query=branch%3Amaster)
Expand Down
18 changes: 18 additions & 0 deletions docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,24 @@ cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release
cmake --build build -j $(getconf _NPROCESSORS_ONLN)
```

### Cross-compiling for arm64 (aarch64) on Debian or Ubuntu

First, set up the dependencies for cross-compilation:

```bash
Packaging/nix/debian-cross-aarch64-prep.sh
```

Then, build DevilutionX using the cross-compilation CMake toolchain file:

```bash
cmake -S. -Bbuild-aarch64-rel \
-DCMAKE_TOOLCHAIN_FILE=../CMake/platforms/aarch64-linux-gnu.toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DCPACK=ON \
-DDEVILUTIONX_SYSTEM_LIBFMT=OFF
cmake --build build-aarch64-rel -j $(getconf _NPROCESSORS_ONLN) --target package
```

</details>

<details><summary>macOS</summary>
Expand Down

0 comments on commit dd31034

Please sign in to comment.