File ci.obscpio of Package AppImageLauncher
07070100000000000081a400000000000000000000000168cf694000000013000000000000000000000000000000000000001100000000ci/.dockerignore*
!install-deps.sh
07070100000001000081a400000000000000000000000168cf6940000002ab000000000000000000000000000000000000000e00000000ci/DockerfileFROM ubuntu:focal
# tell scripts that we're building in an automated release scenario
ENV CI=1
# we re-use the DOCKER_PLATFORM to tell the build scripts about the build target architecture without the need to use uname
# the build scripts will have to map the architecture to names Debian/RPM/AppImage support
ARG DOCKER_PLATFORM
ENV DOCKER_PLATFORM="${DOCKER_PLATFORM}"
# we need to provide some writable $HOME for the (random) used ID we use in the build script
RUN install -d -m 0777 /home/user
ENV HOME=/home/user
# let the install script do the heavy lifting (easier than replicating the complex behavior in a Dockerfile)
COPY install-deps.sh /
RUN bash -xe install-deps.sh
07070100000002000081ed00000000000000000000000168cf6940000009ef000000000000000000000000000000000000001900000000ci/build-docker-image.sh#! /bin/bash
if [[ "$DOCKER_PLATFORM" == "" ]]; then
echo "Usage: env $DOCKER_PLATFORM=... bash $0"
exit 1
fi
set -euo pipefail
# the other script sources this script, therefore we have to support that use case
if [[ "${BASH_SOURCE[*]}" != "" ]]; then
this_dir="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
else
this_dir="$(readlink -f "$(dirname "$0")")"
fi
# we need a "docker-container" type builder to make use of all the buildx features regarding caching and multi-arch
# support
builder_name="appimagelauncher-builder"
if ! docker buildx inspect "$builder_name" &>/dev/null; then
echo "Docker builder $builder_name not found, creating"
docker buildx create --name="$builder_name" --driver=docker-container --bootstrap
else
echo "Using existing Docker builder $builder_name found"
fi
image=ghcr.io/theassassin/appimagelauncher-build
branch="$(git rev-parse --abbrev-ref HEAD | tr -c 'A-Za-z0-9-' '_')"
# append platform to Docker image tag since we can't push separate (multi-arch) images to the same name without
# creating the manifest manually
# see https://github.com/docker/build-push-action/issues/671
platform_suffix="$(echo -n "$DOCKER_PLATFORM" | tr -c 'A-Za-z0-9-' '_')"
current_branch_tag="${image}:${branch}_${platform_suffix}"
master_branch_tag="${image}:master_${platform_suffix}"
docker_command=(
docker buildx build
--builder "$builder_name"
--load # --output=type=docker
--pull
--platform "$DOCKER_PLATFORM"
--build-arg DOCKER_PLATFORM="$DOCKER_PLATFORM"
# cache from the current branch's image
--cache-from type=registry,ref="$current_branch_tag"
# we can always cache from the master branch's image
--cache-from type=registry,ref="$master_branch_tag"
--tag "$current_branch_tag"
)
# if we are building on GitHub actions, we can also push the resulting image
# we skip pull request builds, though; regular branch builds will push the built images (if possible)
# also, skip Dependabot builds, it is not allowed to push images
if [[ "${GITHUB_ACTIONS:-}" != "" ]] && [[ "${GITHUB_EVENT_NAME:-}" != "pull_request" ]] && [[ "${GITHUB_ACTOR:-}" != "dependabot"* ]]; then
echo "Going to push built image"
docker_command+=(
--cache-to type=inline
--push
)
fi
docker_command+=(
"$this_dir"
)
# using inline cache to speed up builds by fetching the image from the GitHub registry first
# this should speed up local builds as well
# if the image hasn't changed, this should be a no-op
"${docker_command[@]}"
07070100000003000081ed00000000000000000000000168cf6940000005bc000000000000000000000000000000000000001600000000ci/build-in-docker.sh#! /bin/bash
if [[ "$DOCKER_PLATFORM" == "" ]]; then
echo "Usage: env DOCKER_PLATFORM=... bash $0"
exit 1
fi
set -x
set -euo pipefail
cd "$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
# sets variables $image, $dockerfile
source build-docker-image.sh
DOCKER_OPTS=()
# fix for https://stackoverflow.com/questions/51195528/rcc-error-in-resource-qrc-cannot-find-file-png
if [ "${CI:-}" != "" ]; then
DOCKER_OPTS+=("--security-opt" "seccomp:unconfined")
fi
# only if there's more than 3G of free space in RAM, we can build in a RAM disk
if [[ "${GITHUB_ACTIONS:-}" != "" ]]; then
echo "Building on GitHub actions, which does not support --tmpfs flag -> building on regular disk"
elif [[ "$(env LC_ALL=C free -m | grep "Mem:" | awk '{print $4}')" -gt 3072 ]]; then
echo "Host system has enough free memory -> building in RAM disk"
DOCKER_OPTS+=("--tmpfs" "/docker-ramdisk:exec,mode=777")
else
echo "Host system does not have enough free memory -> building on regular disk"
fi
[[ -t 0 ]] && DOCKER_OPTS+=("-t")
# run the build with the current user to
# a) make sure root is not required for builds
# b) allow the build scripts to "mv" the binaries into the /out directory
uid="$(id -u)"
# run build
docker run -e BUILD_LITE -e DIST -e ARCH -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ID --rm -i --user "$uid" -w /ws -e CI=1 \
"${DOCKER_OPTS[@]}" \
-v "$(readlink -f ..):/ws" \
"$current_branch_tag" \
bash ci/build.sh
07070100000004000081ed00000000000000000000000168cf694000001785000000000000000000000000000000000000000c00000000ci/build.sh#! /bin/bash
set -euo pipefail
# use RAM disk if possible
if [ -d /dev/shm ] && mount | grep /dev/shm | grep -v -q noexec; then
TEMP_BASE=/dev/shm
elif [ -d /docker-ramdisk ]; then
TEMP_BASE=/docker-ramdisk
else
TEMP_BASE=/tmp
fi
BUILD_DIR="$(mktemp -d -p "$TEMP_BASE" AppImageLauncher-build-XXXXXX)"
cleanup () {
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
}
trap cleanup EXIT
# store repo root as variable
REPO_ROOT="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")"/..)"
OLD_CWD="$(readlink -f .)"
pushd "$BUILD_DIR"
# list available versions of Qt to be able to choose the right one for the build
cat <<\EOF
##########################
# Available Qt versions: #
##########################
EOF
qtchooser -list-versions
echo
# the Docker images provide a clang/clang++ symlink to the actual clang[++] binaries
# see install-deps.sh for more information
cmake_args=(
"-DCMAKE_C_COMPILER=clang"
"-DCMAKE_CXX_COMPILER=clang++"
"-DCMAKE_INSTALL_PREFIX=/usr"
"-DCMAKE_BUILD_TYPE=RelWithDebInfo"
"-DBUILD_TESTING=OFF"
"-DCMAKE_BUILD_TYPE=RelWithDebInfo"
# TODO: we don't necessarily want to hardcode this here
"-DBINFMT_INTERPRETER_PATH_PREPEND_LD_P_NATIVE_PACKAGES_PREFIX=/opt/appimagelauncher.AppDir/"
)
if [[ "${BUILD_LITE:-}" == "" ]]; then
cmake_args+=("-DENABLE_UPDATE_HELPER=ON")
else
cmake_args+=("-DBUILD_LITE=ON")
fi
export QT_SELECT=qt5
cmake "$REPO_ROOT" "${cmake_args[@]}"
make -j$(nproc)
# prepare AppDir
make install DESTDIR=AppDir
ARCH="$(dpkg --print-architecture)"
# "translate" to linuxdeploy/AppImage architecture
# note: linuxdeploy and AppImage differ in i386/i686, but we don't support that any more anyway
case "$ARCH" in
amd64)
ARCH=x86_64
;;
arm64)
ARCH=aarch64
;;
esac
# build release formats
curl -LO https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-"$ARCH".AppImage
curl -LO https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-"$ARCH".AppImage
VERSION=$(src/cli/ail-cli --version | awk '{print $3}')
gha_build="${GITHUB_RUN_NUMBER:-}"
if [[ "$gha_build" != "" ]]; then
VERSION="${VERSION}-gha${gha_build}"
else
VERSION="${VERSION}-local"
fi
# should be overwritten for every output plugin below, this is a fallback only
export LINUXDEPLOY_OUTPUT_APP_NAME=appimagelauncher
LINUXDEPLOY_OUTPUT_VERSION="${VERSION}~$(cd "$REPO_ROOT" && git rev-parse --short HEAD)"
export LINUXDEPLOY_OUTPUT_VERSION
export APPIMAGE_EXTRACT_AND_RUN=1
linuxdeploy_extra_args=()
if [[ "${BUILD_LITE:-}" == "" ]]; then
# configure linuxdeploy-plugin-native_packages
export LDNP_PACKAGE_NAME=appimagelauncher
export LDNP_BUILD="deb rpm"
export LDNP_DESCRIPTION=""
export LDNP_SHORT_DESCRIPTION=""
case "$ARCH" in
x86_64)
rpm_build_arch=x86_64
deb_build_arch=amd64
;;
i?86)
rpm_build_arch=i386
deb_build_arch=i386
;;
aarch64)
rpm_build_arch=aarch64
deb_build_arch=arm64
;;
armhf)
deb_build_arch=armhf
rpm_build_arch=armv7hl
;;
*)
echo "Unsupported architecture: $ARCH"
exit 2
;;
esac
# common meta info
export LDNP_META_URL="https://github.com/TheAssassin/AppImageLauncher"
export LDNP_META_BUG_URL="https://github.com/TheAssassin/AppImageLauncher/issues"
export LDNP_META_VENDOR="TheAssassin"
export LDNP_META_DEB_DEPENDS="systemd, libgl1, libfontconfig1, libharfbuzz0b, libfribidi0"
export LDNP_META_DEB_ARCHITECTURE="$deb_build_arch"
export LDNP_META_DEB_PRE_DEPENDS="bash"
export LDNP_DEB_EXTRA_DEBIAN_FILES="${BUILD_DIR}/cmake/debian/postinst;${BUILD_DIR}/cmake/debian/postrm"
export LDNP_META_RPM_REQUIRES="systemd libGL.so.1 libfontconfig.so.1 libfreetype.so.6 libfribidi.so.0 libgpg-error.so.0 libharfbuzz.so.0"
export LDNP_META_RPM_BUILD_ARCH="$rpm_build_arch"
export LDNP_RPM_SCRIPTLET_POST="${BUILD_DIR}/cmake/debian/postinst"
export LDNP_RPM_SCRIPTLET_PREUN="${BUILD_DIR}/cmake/debian/postrm"
# updater is not available for the lite build
linuxdeploy_extra_args+=(
-e "$(find AppDir/usr/lib/*/appimagelauncher/update | head -n1)"
--output native_packages
)
# tools like pipx would have side effects on the build host and it's generally a bit overkill for our purpose
if which python3.13 &> /dev/null; then
# python3.13, installed from the deadsnakes PPA for the Docker builds
python3() {
python3.13 "$@"
}
fi
python3 -m venv venv
venv/bin/pip install git+https://github.com/linuxdeploy/linuxdeploy-plugin-native_packages
export PATH="$PWD/venv/bin:$PATH"
else
linuxdeploy_extra_args+=(
--custom-apprun "$REPO_ROOT"/resources/appimagelauncher-lite-AppRun.sh
--output appimage
)
LDAI_OUTPUT="$(echo appimagelauncher-lite-"$VERSION"-"$ARCH".AppImage | tr '~' -)"
export LDAI_OUTPUT
# since we extracted common parts from the installer built into the AppRun script, we have to copy the "library" script
# before building an AppImage
install "$REPO_ROOT"/resources/appimagelauncher-lite-installer-common.sh "$(readlink -f AppDir/)"
fi
chmod -v +x linuxdeploy*-"$ARCH".AppImage
# workaround for QEMU
for appimage in *.AppImage; do
dd if=/dev/zero bs=1 count=3 seek=8 conv=notrunc of="$appimage"
done
ldd AppDir/usr/bin/AppImageLauncherSettings
./linuxdeploy-"$ARCH".AppImage -v0 \
--appdir "$(readlink -f AppDir)" \
--plugin qt \
-d AppDir/usr/share/applications/appimagelauncher.desktop \
-e "$(find AppDir/usr/lib/*/appimagelauncher/remove | head -n1)" \
"${linuxdeploy_extra_args[@]}"
if [[ "${BUILD_LITE:-}" == "" ]]; then
mv "$LDNP_PACKAGE_NAME"*.{rpm,deb} "$OLD_CWD"
else
mv "$LDAI_OUTPUT" "$OLD_CWD"
fi
07070100000005000081ed00000000000000000000000168cf694000000ff2000000000000000000000000000000000000001300000000ci/install-deps.sh#! /bin/bash
set -euo pipefail
if [[ "$DOCKER_PLATFORM" == "" ]]; then
echo "Usage: env DOCKER_PLATFORM=... bash $0"
exit 2
fi
if [[ "$CI" == "" ]]; then
echo "Caution: this script is supposed to run inside a (disposable) CI environment"
echo "It will alter a system, and should not be run on workstations or alike"
echo "You can export CI=1 to prevent this error from being shown again"
exit 3
fi
case "$DOCKER_PLATFORM" in
linux/amd64|linux/arm/v7|linux/arm64/v8)
;;
*)
echo "Error: unsupported architecture: $DOCKER_PLATFORM"
exit 4
;;
esac
set -x
# this array collects all the packages we want to install
# running as few operations as possible is a runtime optimization
packages=()
# install 32-bit build dependencies and multilib/cross compilers for binfmt-bypass's 32-bit preload library
# must be done before apt-get update, otherwise the packages cannot be found during installation
if [[ "$DOCKER_PLATFORM" == "linux/amd64" ]]; then
dpkg --add-architecture i386
packages+=(
libc6-dev:i386
)
elif [[ "$DOCKER_PLATFORM" == "linux/arm64/v8" ]]; then
dpkg --add-architecture armhf
packages+=(
libc6-dev:armhf
)
fi
# allow setup of PPA
apt-get update
apt-get install -y software-properties-common
# we depend on the deadsnakes PPA to provide a sufficiently recent Python to linuxdeploy-plugin-native_packages
add-apt-repository -y ppa:deadsnakes/ppa
packages=(
libcurl4-openssl-dev
libfuse-dev
desktop-file-utils
libglib2.0-dev
libcairo2-dev
libssl-dev
ca-certificates
libbsd-dev
qttools5-dev-tools
make
build-essential
git
automake
autoconf
libtool
patch
wget
curl
vim-common
desktop-file-utils
pkg-config
libarchive-dev
libboost-filesystem-dev
librsvg2-dev
librsvg2-bin
libssl-dev
rpm
rpm2cpio
liblzma-dev
# cross-compiling for 32-bit is only really easy with clang, where we can specify the target as a compiler option
# clang -target arm-linux-gnueabihf ...
clang
qtbase5-dev
qt5-qmake
qtdeclarative5-dev
# libappimage
libgcrypt-dev
argagg-dev
nlohmann-json3-dev
libgpgme-dev
libzstd-dev
# linuxdeploy-plugin-native_packages
# see also above re. deadsnakes PPA
python3.13-venv
)
# headless install
export DEBIAN_FRONTEND=noninteractive
apt-get -y --no-install-recommends install "${packages[@]}"
# install more recent CMake and patchelf
cmake_arch="$(dpkg --print-architecture)"
case "$cmake_arch" in
amd64)
cmake_arch=x86_64
;;
arm64)
cmake_arch=aarch64
;;
armhf)
patchelf_arch=armv7l
;;
esac
patchelf_arch="${patchelf_arch:-$cmake_arch}"
curl -L https://artifacts.assassinate-you.net/prebuilt-cmake/cmake-v3.29.6-ubuntu-focal-"${cmake_arch}".tar.gz | \
tar xz --strip-components=1 -C /usr
curl -L https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-"$patchelf_arch".tar.gz | tar xz -C/usr/local
# g{cc,++}-multilib usually install these dependencies for us
# however, as the multilib stuff is not available for ARM, we have to install these dev packages ourselves
# we can't really predict the names of the packages (they differ on different distros/releases)
# therefore, we have to install the other dependencies first to be able to query them with dpkg -l
if [[ "$DOCKER_PLATFORM" == "linux/arm64/v8" ]] || [[ "$DOCKER_PLATFORM" == "linux/amd64" ]]; then
if [[ "$DOCKER_PLATFORM" == "linux/amd64" ]]; then
arch_32bit=i386
elif [[ "$DOCKER_PLATFORM" == "linux/arm64/v8" ]]; then
arch_32bit=armhf
else
echo "Cannot determine 32-bit architecture matching 64-bit architecture $ARCH"
exit 6
fi
apt-get install -y \
"$(dpkg -l | grep libgcc | grep dev | awk '{print $2}' | cut -d: -f1 | uniq)":"$arch_32bit" \
"$(dpkg -l | grep libstdc++ | grep dev | awk '{print $2}' | cut -d: -f1 | uniq)":"$arch_32bit"
fi
07070100000006000041ed00000000000000000000000168cf694000000000000000000000000000000000000000000000000300000000ci07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000b00000000TRAILER!!!