CI: Update AppImage to 22.04 + use LinuxDeploy

This commit is contained in:
Stenzek 2023-09-05 22:03:02 +10:00
parent 519367555b
commit eb07d698cd
8 changed files with 121 additions and 251 deletions

View file

@ -202,7 +202,7 @@ jobs:
linux-build: linux-build:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2.3.1 - uses: actions/checkout@v2.3.1
with: with:
@ -212,14 +212,16 @@ jobs:
shell: bash shell: bash
run: | run: |
# Workaround for https://github.com/actions/runner-images/issues/675 # Workaround for https://github.com/actions/runner-images/issues/675
# TODO: Update to LLVM 18 scripts/retry.sh wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo scripts/retry.sh apt-add-repository -n 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main'
sudo scripts/retry.sh apt-get update && sudo scripts/retry.sh apt-get update &&
sudo scripts/retry.sh apt-get -y install \ sudo scripts/retry.sh apt-get -y install \
cmake ninja-build ccache libegl1-mesa-dev libevdev-dev libwayland-dev libwayland-egl-backend-dev libxrandr-dev libdbus-1-dev \ cmake ninja-build ccache libegl1-mesa-dev libevdev-dev libwayland-dev libwayland-egl-backend-dev libxrandr-dev libdbus-1-dev \
extra-cmake-modules libcurl4-openssl-dev libssl-dev libasound2-dev libpulse-dev libx11-xcb-dev build-essential git libclang-dev \ extra-cmake-modules libcurl4-openssl-dev libssl-dev libasound2-dev libpulse-dev libx11-xcb-dev build-essential git libclang-dev \
libclang-11-dev libclang-12-dev patchelf libglib2.0-dev libfontconfig1-dev libharfbuzz-dev libjpeg-dev libpng-dev libfreetype-dev \ libclang-11-dev libclang-12-dev patchelf libglib2.0-dev libfontconfig1-dev libharfbuzz-dev libjpeg-dev libpng-dev libfreetype-dev \
libinput-dev libxcb-*-dev libxkbcommon-dev libxkbcommon-x11-dev libxrender-dev libwayland-dev libgl1-mesa-dev libegl-dev \ libinput-dev libxcb-*-dev libxkbcommon-dev libxkbcommon-x11-dev libxrender-dev libwayland-dev libgl1-mesa-dev libegl-dev \
libegl1-mesa-dev libgl1-mesa-dev libssl-dev libx11-dev libx11-xcb-dev llvm-12 lld-12 clang-12 libegl1-mesa-dev libgl1-mesa-dev libssl-dev libx11-dev libx11-xcb-dev libfuse2 llvm-16 lld-16 clang-16
- name: Cache Dependencies - name: Cache Dependencies
id: cache-deps id: cache-deps
@ -237,10 +239,10 @@ jobs:
run: | run: |
mkdir build mkdir build
cd build cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_NOGUI_FRONTEND=OFF -DBUILD_QT_FRONTEND=ON -DBUILD_TESTS=OFF -DUSE_EGL=ON -DUSE_SDL2=ON -DUSE_WAYLAND=ON -DUSE_X11=ON -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_PREFIX_PATH=$HOME/deps -DCMAKE_TOOLCHAIN_FILE=../scripts/clang-toolchain.cmake .. cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_NOGUI_FRONTEND=OFF -DBUILD_QT_FRONTEND=ON -DBUILD_TESTS=OFF -DUSE_WAYLAND=ON -DUSE_X11=ON -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_PREFIX_PATH=$HOME/deps -DCMAKE_TOOLCHAIN_FILE=../scripts/clang-toolchain.cmake ..
cmake --build . --parallel cmake --build . --parallel
cd .. cd ..
scripts/make-appimage.sh $(realpath ./build) $(realpath .) $HOME/deps DuckStation-x64 scripts/make-appimage.sh $(realpath .) $(realpath ./build) $HOME/deps DuckStation-x64
- name: Upload Qt AppImage - name: Upload Qt AppImage
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v1
@ -262,7 +264,7 @@ jobs:
- name: Generate AppStream XML - name: Generate AppStream XML
run: | run: |
scripts/flatpak/generate-metainfo.sh scripts/flatpak/org.duckstation.duckstation.metainfo.xml scripts/generate-metainfo.sh scripts/flatpak/org.duckstation.duckstation.metainfo.xml
cat scripts/flatpak/org.duckstation.duckstation.metainfo.xml cat scripts/flatpak/org.duckstation.duckstation.metainfo.xml
flatpak run org.freedesktop.appstream-glib validate scripts/flatpak/org.duckstation.duckstation.metainfo.xml flatpak run org.freedesktop.appstream-glib validate scripts/flatpak/org.duckstation.duckstation.metainfo.xml

View file

@ -1,5 +1,5 @@
set(CMAKE_C_COMPILER /usr/bin/clang-12) set(CMAKE_C_COMPILER /usr/bin/clang-16)
set(CMAKE_CXX_COMPILER /usr/bin/clang++-12) set(CMAKE_CXX_COMPILER /usr/bin/clang++-16)
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld") set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld") set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld") set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")

BIN
scripts/duckstation-qt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View file

@ -47,8 +47,8 @@
], ],
"post-install": [ "post-install": [
"cp -a \"${FLATPAK_BUILDER_BUILDDIR}/bin\" ${FLATPAK_DEST}", "cp -a \"${FLATPAK_BUILDER_BUILDDIR}/bin\" ${FLATPAK_DEST}",
"install -Dm644 data/resources/images/duck.png ${FLATPAK_DEST}/share/icons/hicolor/512x512/apps/org.duckstation.duckstation.png", "install -Dm644 scripts/duckstation-qt.png ${FLATPAK_DEST}/share/icons/hicolor/512x512/apps/org.duckstation.duckstation.png",
"install -Dm644 scripts/flatpak/duckstation-qt.desktop ${FLATPAK_DEST}/share/applications/org.duckstation.duckstation.desktop", "install -Dm644 scripts/duckstation-qt.desktop ${FLATPAK_DEST}/share/applications/org.duckstation.duckstation.desktop",
"desktop-file-edit --set-key=Icon --set-value=org.duckstation.duckstation ${FLATPAK_DEST}/share/applications/org.duckstation.duckstation.desktop", "desktop-file-edit --set-key=Icon --set-value=org.duckstation.duckstation ${FLATPAK_DEST}/share/applications/org.duckstation.duckstation.desktop",
"install -Dm644 scripts/flatpak/org.duckstation.duckstation.metainfo.xml ${FLATPAK_DEST}/share/metainfo/org.duckstation.duckstation.metainfo.xml" "install -Dm644 scripts/flatpak/org.duckstation.duckstation.metainfo.xml ${FLATPAK_DEST}/share/metainfo/org.duckstation.duckstation.metainfo.xml"
] ]

View file

@ -25,278 +25,146 @@
# #
# For more information, please refer to <http://unlicense.org/> # For more information, please refer to <http://unlicense.org/>
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
function retry_command {
# Package servers tend to be unreliable at times..
# Retry a bunch of times.
local RETRIES=10
for i in $(seq 1 "$RETRIES"); do
"$@" && break
if [ "$i" == "$RETRIES" ]; then
echo "Command \"$@\" failed after ${RETRIES} retries."
exit 1
fi
done
}
if [ "$#" -ne 4 ]; then if [ "$#" -ne 4 ]; then
echo "Syntax: $0 <path to build directory> <path to root directory> <deps prefix> <output name>" echo "Syntax: $0 <path to duckstation directory> <path to build directory> <deps prefix> <output name>"
exit 1 exit 1
fi fi
BUILDDIR=$1 ROOTDIR=$1
ROOTDIR=$2 BUILDDIR=$2
DEPSDIR=$3 DEPSDIR=$3
NAME=$4 NAME=$4
BINDIR="$DSDIR/bin"
BINARY=duckstation-qt BINARY=duckstation-qt
APPDIRNAME=DuckStation.AppDir APPDIRNAME=DuckStation.AppDir
STRIP=llvm-strip-12 STRIP=strip
declare -a SYSLIBS=( declare -a MANUAL_QT_LIBS=(
"libz.so.1"
"libuuid.so.1"
"libapparmor.so.1"
"libblkid.so.1"
"libbsd.so.0"
"libdbus-1.so.3"
"libgcrypt.so.20"
"liblzma.so.5"
"libmount.so.1"
"libnsl.so.1"
"libpcre.so.3"
"libselinux.so.1"
"libsystemd.so.0"
"libudev.so.1"
"libwrap.so.0"
"libharfbuzz.so.0"
"libX11.so.6"
"libX11-xcb.so.1"
"libXau.so.6"
"libXcomposite.so.1"
"libXcursor.so.1"
"libXdamage.so.1"
"libXdmcp.so.6"
"libXext.so.6"
"libXfixes.so.3"
"libXi.so.6"
"libXinerama.so.1"
"libXrandr.so.2"
"libXrender.so.1"
"libXxf86vm.so.1"
"libasyncns.so.0"
"libcrypto.so.1.1"
"liblz4.so.1"
"libpulse.so.0"
"libxcb.so.1"
"libxcb-render.so.0"
"libxcb-shm.so.0"
"libxkbcommon.so.0"
"libxkbcommon-x11.so.0"
"pulseaudio/libpulsecommon-13.99.so"
"libfreetype.so.6"
"libpcre2-16.so.0"
"libexpat.so.1"
"libffi.so.7"
"libgraphite2.so.3"
"libresolv.so.2"
"libgpg-error.so.0"
"libpcre2-16.so.0"
"libxcb-icccm.so.4"
"libxcb-image.so.0"
"libxcb-keysyms.so.1"
"libxcb-randr.so.0"
"libxcb-render.so.0"
"libxcb-render-util.so.0"
"libxcb-shape.so.0"
"libxcb-sync.so.1"
"libxcb-cursor.so.0"
"libxcb-util.so.1"
"libxcb-xfixes.so.0"
"libxcb-xkb.so.1"
"libevdev.so.2"
"libgudev-1.0.so.0"
"libinput.so.10"
"libjpeg.so.8"
"libmtdev.so.1"
"libpng16.so.16"
"libuuid.so.1"
"libSM.so.6"
"libICE.so.6"
"libfontconfig.so.1"
"libglib-2.0.so.0"
"libcurl-gnutls.so.4"
"libnghttp2.so.14"
"libidn2.so.0"
"librtmp.so.1"
"libssh.so.4"
"libpsl.so.5"
"libnettle.so.7"
"libgnutls.so.30"
"libgssapi_krb5.so.2"
"libldap_r-2.4.so.2"
"liblber-2.4.so.2"
"libbrotlidec.so.1"
"libunistring.so.2"
"libhogweed.so.5"
"libgmp.so.10"
"libp11-kit.so.0"
"libtasn1.so.6"
"libkrb5.so.3"
"libk5crypto.so.3"
"libcom_err.so.2"
"libkrb5support.so.0"
"libsasl2.so.2"
"libgssapi.so.3"
"libbrotlicommon.so.1"
"libkeyutils.so.1"
"libheimntlm.so.0"
"libkrb5.so.26"
"libasn1.so.8"
"libhcrypto.so.4"
"libroken.so.18"
"libwind.so.0"
"libheimbase.so.1"
"libhx509.so.5"
"libsqlite3.so.0"
"libcrypt.so.1"
"libdbus-1.so.3"
)
declare -a DEPLIBS=(
"libSDL2-2.0.so.0"
)
declare -a QTLIBS=(
"libQt6Core.so.6"
"libQt6Gui.so.6"
"libQt6Network.so.6"
"libQt6OpenGL.so.6"
"libQt6Svg.so.6"
"libQt6WaylandClient.so.6"
"libQt6WaylandCompositor.so.6"
"libQt6WaylandEglClientHwIntegration.so.6" "libQt6WaylandEglClientHwIntegration.so.6"
"libQt6WaylandEglCompositorHwIntegration.so.6"
"libQt6Widgets.so.6"
"libQt6XcbQpa.so.6"
) )
declare -a QTPLUGINS=( declare -a MANUAL_QT_PLUGINS=(
"plugins/iconengines" "wayland-decoration-client"
"plugins/imageformats" "wayland-graphics-integration-client"
"plugins/platforms" "wayland-shell-integration"
#"plugins/platformthemes" # Enable this if we want to ship GTK+ themes at any point.
"plugins/wayland-decoration-client"
"plugins/wayland-graphics-integration-client"
"plugins/wayland-graphics-integration-server"
"plugins/wayland-shell-integration"
"plugins/xcbglintegrations"
) )
set -e set -e
if [ ! -f appimagetool-x86_64.AppImage ]; then LINUXDEPLOY=./linuxdeploy-x86_64.AppImage
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64.AppImage
chmod +x appimagetool-x86_64.AppImage APPIMAGETOOL=./appimagetool-x86_64.AppImage
PATCHELF=patchelf
if [ ! -f "$LINUXDEPLOY" ]; then
retry_command wget -O "$LINUXDEPLOY" https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
chmod +x "$LINUXDEPLOY"
fi
if [ ! -f "$LINUXDEPLOY_PLUGIN_QT" ]; then
retry_command wget -O "$LINUXDEPLOY_PLUGIN_QT" https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
chmod +x "$LINUXDEPLOY_PLUGIN_QT"
fi
if [ ! -f "$APPIMAGETOOL" ]; then
retry_command wget -O "$APPIMAGETOOL" https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
chmod +x "$APPIMAGETOOL"
fi fi
OUTDIR=$(realpath "./$APPDIRNAME") OUTDIR=$(realpath "./$APPDIRNAME")
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}") SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
rm -fr "$OUTDIR" rm -fr "$OUTDIR"
mkdir "$OUTDIR"
mkdir -p "$OUTDIR/usr/bin" "$OUTDIR/usr/lib" "$OUTDIR/usr/lib/pulseaudio" # Why the nastyness? linuxdeploy strips our main binary, and there's no option to turn it off.
# It also doesn't strip the Qt libs. We can't strip them after running linuxdeploy, because
# patchelf corrupts the libraries (but they still work), but patchelf+strip makes them crash
# on load. So, make a backup copy, strip the original (since that's where linuxdeploy finds
# the libs to copy), then swap them back after we're done.
# Isn't Linux packaging amazing?
echo "Copying binary and resources..." rm -fr "$DEPSDIR.bak"
cp -a "$BUILDDIR/bin"/* "$OUTDIR/usr/bin" cp -a "$DEPSDIR" "$DEPSDIR.bak"
IFS="
# We don't need tests "
rm -f "$OUTDIR"/usr/bin/*-tests for i in $(find "$DEPSDIR" -iname '*.so'); do
echo "Stripping deps library ${i}"
# Patch RPATH so the binary goes hunting for shared libraries in the AppDir instead of system. strip "$i"
echo "Patching RPATH in ${BINARY}..."
patchelf --set-rpath '$ORIGIN/../lib' "$OUTDIR/usr/bin/$BINARY"
# Currently we leave the main binary unstripped, uncomment if this is not desired.
#$STRIP "$OUTDIR/usr/bin/$BINARY"
# Libraries we pull in from the system.
echo "Copying system libraries..."
for lib in "${SYSLIBS[@]}"; do
blib=$(basename "$lib")
if [ -f "/lib/x86_64-linux-gnu/$lib" ]; then
cp "/lib/x86_64-linux-gnu/$lib" "$OUTDIR/usr/lib/$blib"
elif [ -f "$CHROOT/usr/lib/x86_64-linux-gnu/$lib" ]; then
cp "$CHROOT/usr/lib/x86_64-linux-gnu/$lib" "$OUTDIR/usr/lib/$blib"
elif [ -f "$CHROOT/lib/$lib" ]; then
cp "$CHROOT/lib/$lib" "$OUTDIR/usr/lib/$blib"
elif [ -f "$CHROOT/usr/lib/$lib" ]; then
cp "$CHROOT/usr/lib/$lib" "$OUTDIR/usr/lib/$blib"
else
echo "*** Failed to find '$blib'"
exit 1
fi
$STRIP "$OUTDIR/usr/lib/$blib"
done done
# Dependencies we built, at this point it's just SDL. echo "Copying desktop file..."
echo "Copying dependency libraries..." cp "$ROOTDIR/scripts/duckstation-qt.desktop" "org.duckstation.duckstation.desktop"
for lib in "${DEPLIBS[@]}"; do cp "$ROOTDIR/scripts/duckstation-qt.png" "duckstation-qt.png"
blib=$(basename "$lib")
if [ -f "$DEPSDIR/lib/$lib" ]; then
cp "$DEPSDIR/lib/$lib" "$OUTDIR/usr/lib/$blib"
else
echo "*** Failed to find '$blib'"
exit 1
fi
$STRIP "$OUTDIR/usr/lib/$blib" echo "Running linuxdeploy to create AppDir..."
EXTRA_QT_PLUGINS="core;gui;network;svg;waylandclient;widgets;xcbqpa" \
EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so" \
QMAKE="$DEPSDIR/bin/qmake" \
NO_STRIP="1" \
$LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/duckstation-qt" \
--desktop-file="org.duckstation.duckstation.desktop" --icon-file="duckstation-qt.png"
echo "Copying resources into AppDir..."
cp -a "$BUILDDIR/bin/resources" "$OUTDIR/usr/bin"
# LinuxDeploy's Qt plugin doesn't include Wayland support. So manually copy in the additional Wayland libraries.
echo "Copying Qt Wayland libraries..."
for lib in "${MANUAL_QT_LIBS[@]}"; do
srcpath="$DEPSDIR/lib/$lib"
dstpath="$OUTDIR/usr/lib/$lib"
echo " $srcpath -> $dstpath"
cp "$srcpath" "$dstpath"
$PATCHELF --set-rpath '$ORIGIN' "$dstpath"
done done
echo "Copying Qt libraries..." # .. and plugins.
for lib in "${QTLIBS[@]}"; do echo "Copying Qt Wayland plugins..."
cp -aL "$DEPSDIR/lib/$lib" "$OUTDIR/usr/lib" for GROUP in "${MANUAL_QT_PLUGINS[@]}"; do
$STRIP "$OUTDIR/usr/lib/$lib" srcpath="$DEPSDIR/plugins/$GROUP"
dstpath="$OUTDIR/usr/plugins/$GROUP"
echo " $srcpath -> $dstpath"
mkdir -p "$dstpath"
for srcsopath in $(find "$DEPSDIR/plugins/$GROUP" -iname '*.so'); do
# This is ../../ because it's usually plugins/group/name.so
soname=$(basename "$srcsopath")
dstsopath="$dstpath/$soname"
echo " $srcsopath -> $dstsopath"
cp "$srcsopath" "$dstsopath"
$PATCHELF --set-rpath '$ORIGIN/../../lib:$ORIGIN' "$dstsopath"
done
done done
echo "Copying Qt plugins..." # Restore unstripped deps (for cache).
mkdir -p "$OUTDIR/usr/lib/plugins" rm -fr "$DEPSDIR"
for plugin in "${QTPLUGINS[@]}"; do mv "$DEPSDIR.bak" "$DEPSDIR"
mkdir -p "$OUTDIR/usr/lib/$plugin"
cp -aL "$DEPSDIR/$plugin"/*.so "$OUTDIR/usr/lib/$plugin/"
done
for so in $(find "$OUTDIR/usr/lib/plugins" -iname '*.so'); do # Fix up translations.
# This is ../../ because it's usually plugins/group/name.so rm -fr "$OUTDIR/usr/bin/translations"
echo "Patching RPATH in ${so}..." mv "$OUTDIR/usr/translations" "$OUTDIR/usr/bin"
patchelf --set-rpath '$ORIGIN/../..' "$so" cp -a "$BUILDDIR/bin/translations" "$OUTDIR/usr/bin"
$STRIP "$so"
done
for so in $(find "$OUTDIR/usr/lib" -maxdepth 1); do # Generate AppStream meta-info.
if [ -f "$so" ]; then echo "Generating AppStream metainfo..."
echo "Patching RPATH in ${so}" mkdir -p "$OUTDIR/usr/share/metainfo"
patchelf --set-rpath '$ORIGIN' "$so" "$SCRIPTDIR/generate-metainfo.sh" "$OUTDIR/usr/share/metainfo/org.duckstation.duckstation.appdata.xml"
fi
done
echo "Creating qt.conf..." echo "Generating AppImage..."
cat > "$OUTDIR/usr/bin/qt.conf" << EOF rm -f "$NAME.AppImage"
[Paths] $APPIMAGETOOL -v "$OUTDIR" "$NAME.AppImage"
Plugins = ../lib/plugins
EOF
echo "Creating desktop..."
cat > "$OUTDIR/duckstation-qt.desktop" << EOF
[Desktop Entry]
Type=Application
Name=DuckStation
GenericName=PlayStation 1 Emulator
Comment=Fast PlayStation 1 emulator
Icon=duckstation-qt
TryExec=duckstation-qt
Exec=duckstation-qt %f
Categories=Game;Emulator;Qt;
EOF
cp "$ROOTDIR/data/resources/images/duck.png" "$OUTDIR/duckstation-qt.png"
echo "Creating AppRun..."
cat > "$OUTDIR/AppRun" << EOF
#!/bin/sh
APPDIR=\$(dirname "\$0")
exec "\$APPDIR/usr/bin/$BINARY" "\$@"
EOF
chmod +x "$OUTDIR/AppRun"
echo "Generate AppImage"
./appimagetool-x86_64.AppImage -v "$OUTDIR" "$NAME.AppImage"