Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/scripts/appimage/make-appimage.sh
10595 views
1
#!/usr/bin/env bash
2
3
# SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin <[email protected]>
4
# SPDX-License-Identifier: CC-BY-NC-ND-4.0
5
6
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
7
8
function retry_command {
9
# Package servers tend to be unreliable at times..
10
# Retry a bunch of times.
11
local RETRIES=10
12
13
for i in $(seq 1 "$RETRIES"); do
14
"$@" && break
15
if [ "$i" == "$RETRIES" ]; then
16
echo "Command \"$@\" failed after ${RETRIES} retries."
17
exit 1
18
fi
19
done
20
}
21
22
if [ "$#" -ne 3 ]; then
23
echo "Syntax: $0 <path to duckstation directory> <path to build directory> <output name>"
24
exit 1
25
fi
26
27
ROOTDIR=$1
28
BUILDDIR=$2
29
ASSETNAME=$3
30
31
BINARY=duckstation-qt
32
APPDIRNAME=DuckStation.AppDir
33
STRIP=strip
34
35
declare -a MANUAL_LIBS=(
36
"libz.so.1"
37
"libavcodec.so.62"
38
"libavformat.so.62"
39
"libavutil.so.60"
40
"libswscale.so.9"
41
"libswresample.so.6"
42
"libdiscord-rpc.so"
43
"libharfbuzz.so"
44
"libfreetype.so.6"
45
"libshaderc_shared.so"
46
"libspirv-cross-c-shared.so.0"
47
)
48
49
set -e
50
51
DEPSDIR=$(realpath "$SCRIPTDIR/../../dep/prebuilt/linux-x64")
52
LINUXDEPLOY=./linuxdeploy-x86_64
53
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64
54
APPIMAGETOOL=./appimagetool-x86_64
55
APPIMAGERUNTIME=./runtime-x86_64
56
PATCHELF=patchelf
57
58
if [ ! -f "$LINUXDEPLOY" ]; then
59
retry_command wget -O "$LINUXDEPLOY" https://github.com/duckstation/dependencies/releases/download/appimage-tools/linuxdeploy-x86_64.AppImage
60
chmod +x "$LINUXDEPLOY"
61
fi
62
63
if [ ! -f "$LINUXDEPLOY_PLUGIN_QT" ]; then
64
retry_command wget -O "$LINUXDEPLOY_PLUGIN_QT" https://github.com/duckstation/dependencies/releases/download/appimage-tools/linuxdeploy-plugin-qt-x86_64.AppImage
65
chmod +x "$LINUXDEPLOY_PLUGIN_QT"
66
fi
67
68
if [ ! -f "$APPIMAGETOOL" ]; then
69
retry_command wget -O "$APPIMAGETOOL" https://github.com/duckstation/dependencies/releases/download/appimage-tools/appimagetool-x86_64.AppImage
70
chmod +x "$APPIMAGETOOL"
71
fi
72
73
if [ ! -f "$APPIMAGERUNTIME" ]; then
74
retry_command wget -O "$APPIMAGERUNTIME" https://github.com/stenzek/type2-runtime/releases/download/continuous/runtime-x86_64
75
fi
76
77
OUTDIR=$(realpath "./$APPDIRNAME")
78
rm -fr "$OUTDIR"
79
80
echo "Locating extra libraries..."
81
EXTRA_LIBS_ARGS=()
82
for lib in "${MANUAL_LIBS[@]}"; do
83
srcpath=$(find "$DEPSDIR" -name "$lib")
84
if [ ! -f "$srcpath" ]; then
85
echo "Missinge extra library $lib. Exiting."
86
exit 1
87
fi
88
89
echo "Found $lib at $srcpath."
90
EXTRA_LIBS_ARGS+=("--library=$srcpath")
91
done
92
93
# Why the nastyness? linuxdeploy strips our main binary, and there's no option to turn it off.
94
# It also doesn't strip the Qt libs. We can't strip them after running linuxdeploy, because
95
# patchelf corrupts the libraries (but they still work), but patchelf+strip makes them crash
96
# on load. So, make a backup copy, strip the original (since that's where linuxdeploy finds
97
# the libs to copy), then swap them back after we're done.
98
# Isn't Linux packaging amazing?
99
100
rm -fr "$DEPSDIR.bak"
101
cp -a "$DEPSDIR" "$DEPSDIR.bak"
102
IFS="
103
"
104
for i in $(find "$DEPSDIR" -iname '*.so'); do
105
echo "Stripping deps library ${i}"
106
strip "$i"
107
done
108
109
echo "Running linuxdeploy to create AppDir..."
110
EXTRA_QT_MODULES="core;gui;svg;widgets;xcbqpa;waylandcompositor" \
111
EXTRA_PLATFORM_PLUGINS="libqwayland.so" \
112
DEPLOY_PLATFORM_THEMES="1" \
113
LINUXDEPLOY_EXCLUDED_LIBRARIES="libwayland-cursor*;libwayland-egl*" \
114
QMAKE="$DEPSDIR/bin/qmake" \
115
NO_STRIP="1" \
116
$LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/duckstation-qt" ${EXTRA_LIBS_ARGS[@]} \
117
--desktop-file="$ROOTDIR/scripts/appimage/org.duckstation.DuckStation.desktop" \
118
--icon-file="$ROOTDIR/scripts/appimage/org.duckstation.DuckStation.png" \
119
120
echo "Copying resources into AppDir..."
121
cp -a "$BUILDDIR/bin/resources" "$OUTDIR/usr/bin"
122
123
# Restore unstripped deps (for cache).
124
rm -fr "$DEPSDIR"
125
mv "$DEPSDIR.bak" "$DEPSDIR"
126
127
# Fix up translations.
128
rm -fr "$OUTDIR/usr/bin/translations"
129
mv "$OUTDIR/usr/translations" "$OUTDIR/usr/bin"
130
cp -a "$BUILDDIR/bin/translations" "$OUTDIR/usr/bin"
131
132
# Generate AppStream meta-info.
133
echo "Generating AppStream metainfo..."
134
mkdir -p "$OUTDIR/usr/share/metainfo"
135
"$SCRIPTDIR/generate-metainfo.sh" "$OUTDIR/usr/share/metainfo"
136
137
echo "Generating AppImage..."
138
rm -f "$ASSETNAME"
139
"$APPIMAGETOOL" -v --runtime-file "$APPIMAGERUNTIME" "$OUTDIR" "$ASSETNAME"
140
141