New AppImage build script using Docker.

Using a "regular" (non-Nix) build script under Debian, and appimage-builder to include all
dependencies in the AppImage.
main
Ben Niemann 1 year ago
parent 660d935bdc
commit 1d8de95ea6

@ -0,0 +1,47 @@
version: 1
script: |
cp -aR /src /srcrw
cd /srcrw
python3 waf configure --out=/build --prefix=/usr --release --without-tests
python3 waf build
python3 waf install --destdir=/build/AppDir
python3 -m pip install --disable-pip-version-check --no-warn-script-location -r <(grep -vE '^pyside2\b' etc/requirements.txt) --ignore-installed --root=/build/AppDir --prefix=/usr
AppDir:
path: ./AppDir
app_info:
id: de.odahoda.noisicaa
name: noisicaa
icon: utilities-terminal
version: %VERSION%
exec: usr/bin/python3
exec_args: -m noisicaa.ui.main "$@"
apt:
arch: amd64
sources:
- sourceline: 'deb [arch=amd64] http://deb.debian.org/debian bullseye main'
key_url: 'https://ftp-master.debian.org/keys/archive-key-11.asc'
- sourceline: 'deb [arch=amd64] http://security.debian.org/debian-security bullseye-security main'
key_url: 'https://ftp-master.debian.org/keys/archive-key-11-security.asc'
include: [ %PKGS% ]
exclude: []
runtime:
env:
PYTHONHOME: '${APPDIR}/usr'
PYTHONPATH: '${APPDIR}/usr/lib/noisicaa:${APPDIR}/usr/lib/python3.9/site-packages'
# Patch the APPDIR_LIBRARY_PATH used by APPRUN to generate LD_LIBRARY_PATH within the AppImage.
# We want any existing LD_LIBRARY_PATH to be prepended, so stuff like pipewire's jack emulation
# works correctly.
after_runtime: |
sed -e 's/^APPDIR_LIBRARY_PATH=/APPDIR_LIBRARY_PATH=$LD_LIBRARY_PATH:/' -i AppDir/.env
AppImage:
update-information: None
sign-key: None
arch: x86_64

@ -0,0 +1,148 @@
#!/bin/bash
set -e
export DEBIAN_FRONTEND=noninteractive
echo >/etc/apt/apt.conf.d/00proxy "Acquire::http::Proxy \"http://192.168.143.1:8000\";"
declare -a PKGS
PKGS=(
# General tooling
curl
xz-utils
build-essential
python3.9
python3-setuptools
python3-yaml
# flatbuffer build time deps
cmake
# appimage-builder deps
python3-pip
python3-setuptools
patchelf
desktop-file-utils
libgdk-pixbuf2.0-dev
fakeroot
strace
# Noisicaa build time deps
python3.9-dev
qtbase5-dev
qtdeclarative5-dev
qtquickcontrols2-5-dev
libqt5svg5-dev
libjack-jackd2-dev
libswresample-dev
libfmt-dev
faust
)
# Noisicaa runtime packages
RUNTIME_PKGS=(
bash
python3.9-minimal
python3-pyside2.qtcore
python3-pyside2.qtgui
python3-pyside2.qtwidgets
python3-pyside2.qtquick
python3-pyside2.qtqml
libqt5svg5
qml-module-qtquick-controls
qml-module-qtquick-controls2
qml-module-qtquick-dialogs
qml-module-qtquick-shapes
qml-module-qtquick-layouts
libfmt7
libswresample3
libjack-jackd2-0
# libGL dependencies (should those be bundled?)
libgl1
libglx0
libglvnd0
libx11-6
libdrm2
libbsd0
libmd0
libxau6
libxcb1
libxdmcp6
)
PKGS+=(${RUNTIME_PKGS[*]})
apt-get update
apt-get -y dist-upgrade
apt-get -y install ${PKGS[*]}
rm -fr /build
mkdir /build
mkdir -p /opt/appimage-builder-cache
ln -s /opt/appimage-builder-cache /build/appimage-builder-cache
export MAKEFLAGS=-j$(nproc)
### appimagetool
if [ ! -x /usr/local/bin/appimagetool ]; then
cd /build
curl -o appimagetool-x86_64.AppImage -L https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
chmod a+x appimagetool-x86_64.AppImage
./appimagetool-x86_64.AppImage --appimage-extract
rm -fr /opt/appimagetool
mv squashfs-root /opt/appimagetool
ln -sf /opt/appimagetool/AppRun /usr/local/bin/appimagetool
fi
### flatbuffers
if [ ! -x /usr/local/bin/flatc ]; then
cd /build
curl -L -o flatbuffers.tar.gz https://github.com/google/flatbuffers/archive/c871df7702c46df7bfb1783aebbf49d054f9282e.tar.gz
mkdir flatbuffers
cd flatbuffers
tar -x --gzip -f ../flatbuffers.tar.gz --strip-components=1
cmake -DFLATBUFFERS_BUILD_TESTS=OFF
make
make install
fi
### flatpy
if [ ! -x /usr/local/bin/flatpy ]; then
python3 -m pip install /src/flatpy/
fi
### dep_sort
if [ ! -e /usr/local/include/dep_sort.h ]; then
cd /build
curl -L -o dep_sort.tar.gz https://github.com/graphitemaster/dep_sort/archive/9e96e9426e74e6dc24ba26fdd9c2bee5bab72b0b.tar.gz
mkdir dep_sort
cd dep_sort
tar -x --gzip -f ../dep_sort.tar.gz --strip-components=1
cp dep_sort.h dep_sort.inl dep_sort_stl.h /usr/local/include/
fi
### python build dependencies
cd /src
python3 -m pip install --disable-pip-version-check -r <(grep -vE '^pyside2\b' etc/requirements.txt)
### build appimage
cd /build
python3 -m pip install --disable-pip-version-check appimage-builder
cat /src/appimg/appimage.yaml \
| sed -e "s/%VERSION%/$(cat /src/VERSION)/g" \
| sed -e "s/%PKGS%/$(IFS=,; echo "${RUNTIME_PKGS[*]}")/g" \
>appimage.yaml
appimage-builder --recipe appimage.yaml --skip-tests
ls -lh noisicaa*.AppImage
cp -vf noisicaa*.AppImage /out

@ -0,0 +1,16 @@
#!/bin/bash
set -e
ROOT="$(realpath "$(dirname "$0")"/..)"
cd "${ROOT}"
mkdir -p build
exec &> >(tee build/build_appimg.log)
docker run \
--rm \
--mount type=bind,source="${ROOT}",target=/src,readonly \
--mount type=bind,source="${ROOT}/build",target=/out \
-i -t \
debian:bullseye bash /src/appimg/build.sh

@ -1,134 +0,0 @@
# @begin:license
#
# Copyright (c) 2015-2021, Ben Niemann <pink@odahoda.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license
import json
import os.path
import shutil
import subprocess
import sys
import textwrap
ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
BUILD_DIR = os.path.join(ROOT_DIR, 'build')
OUT_DIR = os.path.join(BUILD_DIR, 'appimg')
APPIMAGETOOL = os.path.join(BUILD_DIR, 'appimagetool-x86_64.AppImage')
PROOT = os.path.join(BUILD_DIR, 'proot')
VERSION = open(os.path.join(ROOT_DIR, 'VERSION'), 'r').read().strip()
def main():
os.makedirs(BUILD_DIR, exist_ok=True)
if not os.path.isfile(APPIMAGETOOL):
subprocess.run(
['wget',
'-O', APPIMAGETOOL,
'https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage'],
check=True)
os.chmod(APPIMAGETOOL, 0o755)
if not os.path.isfile(PROOT):
subprocess.run(
['wget',
'-O', PROOT,
'https://proot.gitlab.io/proot/bin/proot'],
check=True)
os.chmod(PROOT, 0o755)
if os.path.isdir(OUT_DIR):
subprocess.run(['chmod', '-R', '+w', OUT_DIR], check=True)
shutil.rmtree(OUT_DIR)
os.makedirs(OUT_DIR)
subprocess.run(
['nix', 'build', '-f', os.path.join(ROOT_DIR, 'default.nix')],
check=True)
main_drv = json.loads(
subprocess.run(
['nix', 'path-info', '--json', '-f', os.path.join(ROOT_DIR, 'default.nix')],
check=True, stdout=subprocess.PIPE).stdout)
assert len(main_drv) == 1
main_drv = main_drv[0]
derivations = json.loads(
subprocess.run(
['nix', 'path-info', '-r', '--json', '-f', os.path.join(ROOT_DIR, 'default.nix')],
check=True, stdout=subprocess.PIPE).stdout)
for drv in derivations:
assert drv['deriver'].startswith('/nix/store')
assert drv['path']
for path in [drv['path']]:
print(path)
assert path.startswith('/nix/store')
assert os.path.exists(path)
dest = os.path.join(OUT_DIR, path[1:])
if os.path.isdir(path):
shutil.copytree(path, dest, symlinks=True)
else:
os.makedirs(os.path.dirname(dest), exist_ok=True)
shutil.copy2(path, dest)
os.mkdir(os.path.join(OUT_DIR, 'bin'))
shutil.copy2(PROOT, os.path.join(OUT_DIR, 'bin', 'proot'))
shutil.copy2('/usr/bin/unionfs', os.path.join(OUT_DIR, 'bin', 'unionfs'))
os.symlink(os.path.join('..', main_drv['path'][1:], 'bin', 'noisicaa'), os.path.join(OUT_DIR, 'bin', 'noisicaa'))
with open(os.path.join(OUT_DIR, 'AppRun'), 'w') as fp:
fp.write(textwrap.dedent('''\
#!/bin/bash -e
if [ -d /nix/store ]; then
NIXSTORE="${XDG_RUNTIME_DIR}/noisicaa.nix.merged"
mkdir -p "${NIXSTORE}"
"${APPDIR}/bin/unionfs" "${APPDIR}/nix/store:/nix/store" "${NIXSTORE}"
trap "umount \"${NIXSTORE}\"" EXIT
else
NIXSTORE="${APPDIR}/nix/store"
fi
"${APPDIR}/bin/proot" -r / -b "${NIXSTORE}:/nix/store" "${APPDIR}/bin/noisicaa" "$@"
'''))
os.chmod(os.path.join(OUT_DIR, 'AppRun'), 0o755)
with open(os.path.join(OUT_DIR, 'noisicaa.desktop'), 'w') as fp:
fp.write(textwrap.dedent('''\
[Desktop Entry]
Name=noisicaa
Exec=AppRun
Icon=noisicaa
Type=Application
Categories=Utility
'''))
shutil.copy2('data/icons/noisicaa-small.png', os.path.join(OUT_DIR, 'noisicaa.png'))
subprocess.run(
[APPIMAGETOOL,
'-n',
OUT_DIR,
os.path.join(BUILD_DIR, 'noisicaa-{}-x86_64.AppImage'.format(VERSION))],
check=True,
# it gets confused, if e.g. SOURCE_DATE_EPOCH is set, so run with an empty env.
env={})
if __name__ == '__main__':
main()
Loading…
Cancel
Save