From 187b99c9ce4509f378905332243b5ecc316a6887 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Tue, 24 Oct 2023 17:27:54 +0200
Subject: [PATCH] BUILD: Multi-Stage the docker build process

Generate build dockers used to build the application in appimage mode or
in a zip file for windows.

Still some issues with wayland on linux for the appimage, so we force
xcb rendered when not relying on gtk (gnome, xfce, etc, but not tested
there...)

Logs are:
	[07:59:29 DEBUG CC::WINDOW] module_qt_window.cc+62:mod_new: initializing a new window
	[07:59:29 DEBUG CC::WINDOW] module_qt_window.cc+70:mod_new: waiting for the new window, active wait...
	qt.qpa.wayland: Failed to load client buffer integration: "wayland-egl"
	qt.qpa.wayland: Available client buffer integrations: QList("wayland-egl")
	QOpenGLWidget is not supported on this platform.
	QRhiGles2: Failed to create temporary context
	QRhiGles2: Failed to create context
	Failed to create QRhi for QBackingStoreRhiSupport
	QOpenGLWidget: Failed to create context
	[07:59:29 ERROR CC::WINDOW] mpvwidget.cc+268:handleMpvEvent: Should not get event idle (id is 11)
	[07:59:29 DEBUG CC::WINDOW] mpvwidget.cc+216:handleMpvEvent: Detected pause
	[07:59:29 DEBUG CC::WINDOW] mpvwidget.cc+247:handleMpvEvent: Applying unpause
	[07:59:29 DEBUG CC::WINDOW] mpvwidget.cc+224:handleMpvEvent: Detected unpause
	[07:59:29 DEBUG CC::WINDOW] mpvwidget.cc+232:handleMpvEvent: Detected idle
	[07:59:29 DEBUG CC::WINDOW] mpvwidget.cc+234:handleMpvEvent: Applying idle
	[07:59:29 DEBUG CC::WINDOW] module_qt_window.cc+75:mod_new: new window OK!
	QOpenGLWidget: Failed to create context
	Segmentation fault (core dumped)
---
 .dockerignore                                 |   5 +
 .gitignore                                    |   3 -
 .gitlab-ci.yml                                |  16 +--
 BUILD.md                                      | 106 ------------------
 Dockerfile                                    |  48 --------
 Dockerfile.appimage                           |  29 +++++
 Dockerfile.windows                            |  40 +++++++
 README.md                                     |  33 +++++-
 amadeus/amadeus.appdata.xml                   |  21 ++++
 {utils/desktop => amadeus}/amadeus.desktop    |   0
 {utils/desktop => amadeus}/amadeus.png        | Bin
 amadeus/src/main.rs                           |   2 +-
 build/.gitignore                              |   2 +
 lektor_utils/src/open/mod.rs                  |   2 +-
 lektord/c/icon.xpm                            |   2 +-
 lektord/c/module_qt_window.cc                 |   7 +-
 lektord/lektord.appdata.xml                   |  21 ++++
 {utils/desktop => lektord}/lektord.desktop    |   2 +-
 .../desktop/lektor.png => lektord/lektord.png | Bin
 lkt/lkt.appdata.xml                           |  21 ++++
 {utils/desktop => lkt}/lkt.desktop            |   2 +-
 lkt/lkt.png                                   | Bin 0 -> 4692 bytes
 utils/scripts/docker/package_appimages.bash   | 104 +++++++++++++++++
 utils/scripts/docker/package_zip.bash         |  26 +++++
 utils/scripts/docker/prepare_workspace.bash   |  24 ++++
 utils/scripts/docker/setup_base.bash          |  45 ++++++++
 utils/scripts/docker/setup_cross.bash         |  63 +++++++++++
 utils/scripts/docker/touch_files.bash         |  16 +++
 28 files changed, 462 insertions(+), 178 deletions(-)
 delete mode 100644 BUILD.md
 delete mode 100644 Dockerfile
 create mode 100644 Dockerfile.appimage
 create mode 100644 Dockerfile.windows
 create mode 100644 amadeus/amadeus.appdata.xml
 rename {utils/desktop => amadeus}/amadeus.desktop (100%)
 rename {utils/desktop => amadeus}/amadeus.png (100%)
 create mode 100644 build/.gitignore
 create mode 100644 lektord/lektord.appdata.xml
 rename {utils/desktop => lektord}/lektord.desktop (93%)
 rename utils/desktop/lektor.png => lektord/lektord.png (100%)
 create mode 100644 lkt/lkt.appdata.xml
 rename {utils/desktop => lkt}/lkt.desktop (94%)
 create mode 100644 lkt/lkt.png
 create mode 100755 utils/scripts/docker/package_appimages.bash
 create mode 100755 utils/scripts/docker/package_zip.bash
 create mode 100755 utils/scripts/docker/prepare_workspace.bash
 create mode 100755 utils/scripts/docker/setup_base.bash
 create mode 100755 utils/scripts/docker/setup_cross.bash
 create mode 100755 utils/scripts/docker/touch_files.bash

diff --git a/.dockerignore b/.dockerignore
index af0e68c9..44111dfd 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,2 +1,7 @@
 .build/
 .build.*/
+.dockerignore
+
+target/
+appimage/
+Dockerfile
diff --git a/.gitignore b/.gitignore
index 83990fd2..9e8fef6c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,8 +2,6 @@
 target/
 .build/
 .cache/
-build/
-build.*/
 .build.*/
 bin/
 pkg/
@@ -14,7 +12,6 @@ fake/
 config.log
 *\~
 *.AppImage
-appimage/
 *.pro.user
 !*.inc
 !Cargo.lock
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d81782e2..a4f5ac03 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,3 @@
-
 .common_build:
     only:
         - master
@@ -18,13 +17,12 @@
     resource_group: rust_build
     before_script:
         - lsb_release -a
-        - echo -e "[profile.release]\nopt-level = 0" >> "$CARGO_HOME/config.toml"
-        - apt update && apt -y install make libmpv-dev cmake clang clang-format gcc g++ xxd mkvtoolnix
-            libcurl4-openssl-dev libsqlite3-dev manpages man-db libfontconfig-dev
-            qt6-base-dev qt6-declarative-dev qt6-multimedia-dev
+        - apt update && apt -y install make libmpv-dev cmake clang clang-format g++
+            manpages man-db qt6-base-dev qt6-declarative-dev qt6-multimedia-dev
         - cargo --version
     script:
-        - CXX=${cxx_compiler} CC=${c_compiler} cargo build --release
+        - CXX=${cxx_compiler} cargo test  --release
+        - CXX=${cxx_compiler} cargo build --release
 
 variables:
     GIT_DEPTH: 1 # No need to clone all the history
@@ -34,15 +32,13 @@ variables:
 #################################################
 
 build-clang:
-    stage: build
+    stage:    build
     extends: .common_build
     variables:
-        c_compiler: clang
         cxx_compiler: clang++
 
 build-gcc:
-    stage: build
+    stage:    build
     extends: .common_build
     variables:
-        c_compiler: gcc
         cxx_compiler: g++
diff --git a/BUILD.md b/BUILD.md
deleted file mode 100644
index dbd14f8b..00000000
--- a/BUILD.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# Build options for Lektor
-
-## Building a lektor distribution for windows (Cross Compilation)
-
-Windows 64 bit binaries are built from a linux system. Here we will assume you are using an arch
-linux system because it's what I'm using. Install the packages `mingw-w64-gcc`, `mingw-w64-cmake`
-(aur), `mingw-w64-make` (aur). You may also install the `mingw-w64-qt6-*` (aur) packages. For the
-mpv library, install the packages in [utils/arch-pkgs]. Make sure that you have the windows
-toolchain for 64 bit installed. Run the followinf commands:
-
-    (cd utils/arch-pkgs/mingw-w64-shaderc && makepkg -si)
-    yay -Sy mingw-w64-gcc mingw-w64-cmake mingw-w64-make mingw-w64-dlfcn x86_64-w64-mingw32-ldd
-    yay -Sy mingw-w64-mpv                   # Be sure to install it after building shaderc from source
-    yay -Sy mingw-w64-qt6-*                 # You may specify the packages, you may doo the bootstrap thingy here
-    rustup target add x86_64-pc-windows-gnu # Add the windows target, here we build 64bit applications
-    MAKE=x86_64-w64-mingw32-make CMAKE=x86_64-w64-mingw32-cmake CXX=x86_64-w64-mingw32-g++ cargo build --target x86_64-pc-windows-gnu
-
-To produce the zip file for windows users, from the target folder run the following commands:
-
-    mkdir -p lektor/platforms && cd lektor  # Prepare folders
-    cp ../{lkt,amadeus,lektord}.exe .       # Copy the produced executables
-    cp ../lektor_c.dll .                    # Copy the dll for lektord
-
-    for F in $(WINEPATH=/usr/x86_64-w64-mingw32/bin x86_64-w64-mingw32-ldd lektor_c.dll | grep -v "not found" | awk '{print $3}')
-    do
-        cp "$F" . # Copy DLL files
-    done
-    chmod +x *.dll *.dll.*                                                              # Set DLL executable for linux, just in case
-    cp /usr/x86_64-w64-mingw32/lib/qt6/plugins/platforms/qwindows.dll        platforms/ # Copy the windows platform dll for Qt
-    cp /usr/x86_64-w64-mingw32/lib/qt6/plugins/styles/qwindowsvistastyle.dll styles/    # Copy the style dll
-    (cd .. && zip lektor.zip lektor/* lektor/platforms/*)                               # Create the zip file
-
-    # Now you can run lektord and distribute the zip file!
-    ./lektord.exe
-
-> Be sure to have the multilib repos and install the bootstrap `minwg-w64-*-bootstrap` packages
-> first, to avoid the circular dependencies... And be sure to have a lot of time to waste.
-
-## Building a lektor distribution for linux (AppImage)
-
-Note that it is preferable to build AppImages from the older system that you want to support, see
-the [official website](https://appimage.org/). Note that you can run AppImage from anywhere at the
-condition that the target system has fuse2 installed and is newer that the system the AppImage was
-build with.
-
-### Build on host system (ArchLinux)
-
-First you need the LinuxDeploy and AppImageTool binaries. You will need to have fuse2 installed on
-your system. We will assume you are using an *x86_64* system. You can download it their repositories:
-- https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous
-- https://github.com/AppImage/AppImageKit/releases/tag/continuous
-
-As an alternative you can use the following commands and add the `$HOME/.local/bin` folder to you path.
-
-    wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
-    wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-static-x86_64.AppImage
-    mv appimagetool-x86_64.AppImage       ~/.local/bin/appimagetool
-    mv linuxdeploy-static-x86_64.AppImage ~/.local/bin/linuxdeploy
-    chmod +x ~/.local/bin/appimagetool
-    chmod +x ~/.local/bin/linuxdeploy
-
-For the packages needed to build the lektor project, on arch you may install the following packages:
-`qt6-multimedia-ffmpeg`, `qt6-translations`, `qt6-declarative`, `qt6-multimedia`, `qt6-wayland`,
-`qt6-tools`, `qt6-base`, `qt6-svg`, `mpv`, `cmake`, `cmake-extra-modules`. The usual way of
-installing rust is by executing their script:
-
-    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
-After building the lektord executable and .so files, you can use the following commands from the
-target folder (where the executable where generated). We will reference the root folder of the
-lektord repository as `$ROOT`.
-
-    mkdir Amadeus Lektord Lkt # Create one folder for each AppImage
-
-    # Do the thing for Lkt
-    linuxdeploy --appdir Lkt --executable lkt --icon-file $ROOT/utils/desktop/lektor.png --desktop-file $ROOT/utils/desktop/lkt.desktop
-    appimagetool --comp xz --sign --sign-key $YOUR_SIGN_KEY Lkt
-
-    # Do the thing for Lektord
-    linuxdeploy --appdir Lektord --executable lektord --icon-file $ROOT/utils/desktop/lektor.png --desktop-file $ROOT/utils/desktop/lektord.desktop
-    appimagetool --comp xz --sign --sign-key $YOUR_SIGN_KEY Lektord
-
-    # Do the thing for Amadeus
-    linuxdeploy --appdir Amadeus --executable lektord --icon-file $ROOT/utils/desktop/amadeus.png --desktop-file $ROOT/utils/desktop/amadeus.desktop
-    appimagetool --comp xz --sign --sign-key $YOUR_SIGN_KEY Amadeus
-
-### Build in a container (Docker/Podman)
-
-As an alternative you can run the docker which will use debian 12 (bookworm) to try to build an
-AppImage which is compatible with as many systems as possible, note that with Qt6 we won't be able
-to support systems that are too old.
-
-You can use docker (must be configured) or podman, with podman you don't need a root daemon and
-privileges, it will run as your current user. In the latter case your container registry config file
-`/etc/containers/registries.conf` must contains the following content:
-
-    [registries.search]
-    registries = ['docker.io']
-
-When everything is configured you can run the following commands, using either docker or podman.
-Note that you still need fuse2 on the host system.
-
-    mkdir -p appimage
-    podman build --rm -v "$PWD/appimage":/usr/src/lektor/appimage --cap-add SYS_ADMIN --device /dev/fuse .
-    podman image prune -f
-
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 075be434..00000000
--- a/Dockerfile
+++ /dev/null
@@ -1,48 +0,0 @@
-ARG VERSION=1.73
-FROM rust:${VERSION}-bookworm
-WORKDIR /usr/src/lektor
-COPY . .
-
-RUN apt update && apt -y install \
-        make libmpv-dev cmake clang clang-format manpages man-db \
-        qt6-base-dev qt6-declarative-dev qt6-multimedia-dev fuse
-
-RUN mkdir appimagetool \
-    && wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage \
-        -O appimagetool/appimage                  \
-    && chmod +x appimagetool/appimage             \
-    && ./appimagetool/appimage --appimage-extract \
-    && mv squashfs-root appimagetool/
-
-RUN mkdir linuxdeploy \
-    && wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage \
-        -O linuxdeploy/appimage                  \
-    && chmod +x linuxdeploy/appimage             \
-    && ./linuxdeploy/appimage --appimage-extract \
-    && mv squashfs-root linuxdeploy/
-
-RUN CXX=clang++ cargo build --release
-
-RUN ./linuxdeploy/squashfs-root/AppRun           \
-        -v1 --appdir appimage/Lkt                \
-        --executable target/release/lkt          \
-        --icon-file utils/desktop/lektor.png     \
-        --desktop-file utils/desktop/lkt.desktop \
-    && ./appimagetool/squashfs-root/AppRun -v --comp xz appimage/Lkt \
-    && mv Lkt-*.AppImage appimage/ && rm -rf appimage/Lkt/
-
-RUN ./linuxdeploy/squashfs-root/AppRun               \
-        -v1 --appdir appimage/Lektord                \
-        --executable target/release/lektord          \
-        --icon-file utils/desktop/lektor.png         \
-        --desktop-file utils/desktop/lektord.desktop \
-    && ./appimagetool/squashfs-root/AppRun -v --comp xz appimage/Lektord \
-    && mv Lektord-*.AppImage appimage/ && rm -rf appimage/Lektord/
-
-RUN ./linuxdeploy/squashfs-root/AppRun               \
-        -v1 --appdir appimage/Amadeus                \
-        --executable target/release/amadeus          \
-        --icon-file utils/desktop/amadeus.png        \
-        --desktop-file utils/desktop/amadeus.desktop \
-    && ./appimagetool/squashfs-root/AppRun -v --comp xz appimage/Amadeus \
-    && mv Amadeus-*.AppImage appimage/ && rm -rf appimage/Amadeus/
diff --git a/Dockerfile.appimage b/Dockerfile.appimage
new file mode 100644
index 00000000..d768628f
--- /dev/null
+++ b/Dockerfile.appimage
@@ -0,0 +1,29 @@
+FROM    rust:1.73-bullseye AS linux-base
+WORKDIR /usr/src
+COPY    --chmod=0755 utils/scripts/docker/setup_base.bash setup
+RUN     ./setup
+
+FROM    linux-base AS linux-cache
+WORKDIR /usr/src
+COPY    --chmod=0755 utils/scripts/docker/prepare_workspace.bash prepare
+RUN     STAGE=1 ./prepare
+COPY    lektor_procmacros/Cargo.toml    lektor_procmacros
+COPY    lektor_lib/Cargo.toml           lektor_lib
+COPY    lektor_nkdb/Cargo.toml          lektor_nkdb
+COPY    lektor_repo/Cargo.toml          lektor_repo
+COPY    lektor_mpris/Cargo.toml         lektor_mpris
+COPY    kurisu_api/Cargo.toml           kurisu_api
+COPY    lektor_payloads/Cargo.toml      lektor_payloads
+COPY    lektor_utils/Cargo.toml         lektor_utils
+COPY    lkt/Cargo.toml                  lkt
+COPY    lektord/Cargo.toml              lektord
+COPY    amadeus/Cargo.toml              amadeus
+COPY    Cargo.toml Cargo.lock           ./
+RUN     STAGE=2 ./prepare
+
+FROM        linux-cache
+WORKDIR     /usr/src
+COPY        --chmod=0755 utils/scripts/docker/package_appimages.bash package
+COPY        --chmod=0755 utils/scripts/docker/touch_files.bash       touch
+ENTRYPOINT  ./touch && CXX=clang++ cargo test --release && CXX=clang++ cargo build --release && ./package
+
diff --git a/Dockerfile.windows b/Dockerfile.windows
new file mode 100644
index 00000000..e3d2f588
--- /dev/null
+++ b/Dockerfile.windows
@@ -0,0 +1,40 @@
+FROM    archlinux:latest AS mingw64-base
+WORKDIR /usr/src
+COPY    --chmod=0755 utils/scripts/docker/setup_cross.bash setup
+COPY    --chmod=0644 --chown=1000:1000 utils/arch-pkgs/mingw-w64-shaderc /home/devel/mingw-w64-shaderc
+RUN     ./setup
+
+FROM    mingw64-base as mingw64-cache
+USER    devel
+ENV     HOME=/home/devel
+ENV     MAKE=x86_64-w64-mingw32-make
+ENV     CMAKE=x86_64-w64-mingw32-cmake
+ENV     CXX=x86_64-w64-mingw32-g++
+WORKDIR /home/devel
+COPY    --chmod=0755 utils/scripts/docker/prepare_workspace.bash prepare
+RUN     STAGE=1 ./prepare
+COPY    lektor_procmacros/Cargo.toml    lektor_procmacros
+COPY    lektor_lib/Cargo.toml           lektor_lib
+COPY    lektor_nkdb/Cargo.toml          lektor_nkdb
+COPY    lektor_repo/Cargo.toml          lektor_repo
+COPY    lektor_mpris/Cargo.toml         lektor_mpris
+COPY    kurisu_api/Cargo.toml           kurisu_api
+COPY    lektor_payloads/Cargo.toml      lektor_payloads
+COPY    lektor_utils/Cargo.toml         lektor_utils
+COPY    lkt/Cargo.toml                  lkt
+COPY    lektord/Cargo.toml              lektord
+COPY    amadeus/Cargo.toml              amadeus
+COPY    Cargo.toml Cargo.lock           ./
+RUN     STAGE=2 ./prepare --target x86_64-pc-windows-gnu
+
+FROM        mingw64-cache
+USER        devel
+ENV         HOME=/home/devel
+ENV         MAKE=x86_64-w64-mingw32-make
+ENV         CMAKE=x86_64-w64-mingw32-cmake
+ENV         CXX=x86_64-w64-mingw32-g++
+WORKDIR     /home/devel
+COPY        --chmod=0755 utils/scripts/docker/touch_files.bash touch
+COPY        --chmod=0755 utils/scripts/docker/package_zip.bash package
+ENTRYPOINT  ./touch && cargo test --release --target x86_64-pc-windows-gnu && cargo build --release --target x86_64-pc-windows-gnu && ./package
+
diff --git a/README.md b/README.md
index 51e9613b..326de5f5 100644
--- a/README.md
+++ b/README.md
@@ -23,9 +23,9 @@ A Karaoke player made to replace the old bash scripts on Sakura.
 
 ### Prerequisites
 
-- [rust](https://www.rust-lang.org) compiler with version >= 1.72
-- [cmake](https://cmake.org/) at least the version 3.17
-- C++ compiler with [C++20 support](https://en.cppreference.com/w/cpp/20)
+- [rust](https://www.rust-lang.org) compiler with version >= 1.70
+- [cmake](https://cmake.org/) at least the version 3.18
+- C++ compiler with [C++17 support](https://en.cppreference.com/w/cpp/17)
 - [mpv](https://mpv.io/) development library
 - [Qt6](https://www.qt.io/) development library: QtCore, QtWidgets, QtOpenGL, QtOpenGLWidgets.
 
@@ -36,7 +36,7 @@ from the `graphviz` package to be installed for that script to work.
 ### Building instructions
 
 The manual way of installing and setting up lektor. We will suppose that cargo will place all the
-binaries inside the `target` folder:
+binaries inside the `target` folder and that you have all the libraries installed correctly.
 
     cargo build --release
     install -CD -m 0755 utils/scripts/kagary.py $HOME/.local/bin/kagary
@@ -49,7 +49,30 @@ compiler: `CXX=clang++ cargo build --release`. By default the build artifacts fo
 placed in the `.build` folder at the root of the project. If you specify another compiler they will
 be placed in the `.build.$(basename "$CXX")` folder.
 
-For more informations about builds options, see the [BUILD.md] file.
+You can use podman (must be configured) or docker, with podman you don't need a root daemon and
+privileges, it will run as your current user. In the former case your container registry config file
+`/etc/containers/registries.conf` must contains the following content:
+
+    [registries.search]
+    registries = ['docker.io']
+
+When everything is configured you can run the following commands, using either docker or podman:
+
+    # AppImage build
+    podman build -t lektor_appimage -f Dockerfile.appimage
+    podman run -v $PWD/build:/build -v $PWD:/src lektor_appimage
+
+    # Windows build
+    podman build -t lektor_windows -f Dockerfile.windows
+    podman run -v $PWD/build:/build -v $PWD:/src lektor_windows
+
+> Note that the generated AppImages won't be signed, you can signed them by extracting them, and
+> repacking them with you gpg key, here with Amadeus as an example. You will need to have downloaded
+> the appimage utility.
+>
+>     ./Amadeus-x86_64.AppImage --appimage-extract
+>     mv squashfs-root Amadeus
+>     appimagetool --comp xz --sign --sign-key $YOUR_SIGN_KEY Amadeus
 
 ## How to use lektor
 
diff --git a/amadeus/amadeus.appdata.xml b/amadeus/amadeus.appdata.xml
new file mode 100644
index 00000000..9e5705ba
--- /dev/null
+++ b/amadeus/amadeus.appdata.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component type="desktop-application">
+	<id>amadeus</id>
+	<metadata_license>MIT</metadata_license>
+	<project_license>MIT</project_license>
+	<name>Amadeus</name>
+	<summary>Amadeus client for lektord</summary>
+	<description>
+		<p>Amadeus is a GUI client written in Rust for the lektord daemon.</p>
+	</description>
+	<launchable type="desktop-id">amadeus.desktop</launchable>
+	<url type="homepage">https://kurisu.iiens.net</url>
+	<screenshots>
+		<screenshot type="default">
+			<image></image>
+		</screenshot>
+	</screenshots>
+	<provides>
+		<id>amadeus.desktop</id>
+	</provides>
+</component>
diff --git a/utils/desktop/amadeus.desktop b/amadeus/amadeus.desktop
similarity index 100%
rename from utils/desktop/amadeus.desktop
rename to amadeus/amadeus.desktop
diff --git a/utils/desktop/amadeus.png b/amadeus/amadeus.png
similarity index 100%
rename from utils/desktop/amadeus.png
rename to amadeus/amadeus.png
diff --git a/amadeus/src/main.rs b/amadeus/src/main.rs
index 9f97cd8d..ffb31bf7 100644
--- a/amadeus/src/main.rs
+++ b/amadeus/src/main.rs
@@ -49,7 +49,7 @@ fn main() -> Result<()> {
         id: Some("Amadeus".to_string()),
         window: iced::window::Settings {
             icon: Some(iced::window::icon::from_file_data(
-                include_bytes!("../../utils/desktop/amadeus.png"),
+                include_bytes!("../amadeus.png"),
                 Some(image::ImageFormat::Png),
             )?),
             resizable: true,
diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644
index 00000000..d6b7ef32
--- /dev/null
+++ b/build/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/lektor_utils/src/open/mod.rs b/lektor_utils/src/open/mod.rs
index 20b9bdc0..e20e99a3 100644
--- a/lektor_utils/src/open/mod.rs
+++ b/lektor_utils/src/open/mod.rs
@@ -68,7 +68,7 @@
 
 #[cfg(windows)]
 #[path = "windows.rs"]
-mod windows;
+mod os;
 
 #[cfg(target_os = "macos")]
 #[path = "macos.rs"]
diff --git a/lektord/c/icon.xpm b/lektord/c/icon.xpm
index dbebed39..442f00ec 100644
--- a/lektord/c/icon.xpm
+++ b/lektord/c/icon.xpm
@@ -1,5 +1,5 @@
 /* XPM */
-static char *icon[] = {
+static const char *const icon[] = {
 /* columns rows colors chars-per-pixel */
 "32 32 9 1 ",
 "  c #0E001D",
diff --git a/lektord/c/module_qt_window.cc b/lektord/c/module_qt_window.cc
index 18697e14..90012eba 100644
--- a/lektord/c/module_qt_window.cc
+++ b/lektord/c/module_qt_window.cc
@@ -17,7 +17,12 @@ ___create_mpv_widget(void *arg)
     setlocale(LC_NUMERIC, "C");
     qt_window->main_window = new MainWindow(qt_window);
     qt_window->main_window->show();
-    return std::bit_cast<void *>((static_cast<size_t>(app.exec())));
+
+    // Becaust of debian bullseye we don't have bit_cast and must use a memcpy...
+    const size_t ret = static_cast<size_t>(app.exec());
+    void *ret_ptr    = nullptr;
+    std::memcpy(&ret_ptr, &ret, sizeof(void *));
+    return ret_ptr;
 }
 
 #if defined(LKT_OS_MINGW) && (LKT_OS_MINGW == 1)
diff --git a/lektord/lektord.appdata.xml b/lektord/lektord.appdata.xml
new file mode 100644
index 00000000..c0d6c25c
--- /dev/null
+++ b/lektord/lektord.appdata.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component type="desktop-application">
+	<id>lektord</id>
+	<metadata_license>MIT</metadata_license>
+	<project_license>MIT</project_license>
+	<name>Lektord</name>
+	<summary>The lektord daemon</summary>
+	<description>
+		<p>The lektord daemon.</p>
+	</description>
+	<launchable type="desktop-id">lektord.desktop</launchable>
+	<url type="homepage">https://kurisu.iiens.net</url>
+	<screenshots>
+		<screenshot type="default">
+			<image></image>
+		</screenshot>
+	</screenshots>
+	<provides>
+		<id>lektord.desktop</id>
+	</provides>
+</component>
diff --git a/utils/desktop/lektord.desktop b/lektord/lektord.desktop
similarity index 93%
rename from utils/desktop/lektord.desktop
rename to lektord/lektord.desktop
index 5edb11e1..025c33b3 100644
--- a/utils/desktop/lektord.desktop
+++ b/lektord/lektord.desktop
@@ -2,7 +2,7 @@
 Version=1.0
 Type=Application
 Name=Lektord
-Icon=lektor
+Icon=lektord
 GenericName=Lektor deamon
 Comment=The lektor deamon
 Keywords=video;audio
diff --git a/utils/desktop/lektor.png b/lektord/lektord.png
similarity index 100%
rename from utils/desktop/lektor.png
rename to lektord/lektord.png
diff --git a/lkt/lkt.appdata.xml b/lkt/lkt.appdata.xml
new file mode 100644
index 00000000..97c49143
--- /dev/null
+++ b/lkt/lkt.appdata.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component type="desktop-application">
+	<id>lkt</id>
+	<metadata_license>MIT</metadata_license>
+	<project_license>MIT</project_license>
+	<name>Lkt</name>
+	<summary>Lkt client for lektord</summary>
+	<description>
+		<p>Lkt is a GUI client written in Rust for the lektord daemon.</p>
+	</description>
+	<launchable type="desktop-id">lkt.desktop</launchable>
+	<url type="homepage">https://kurisu.iiens.net</url>
+	<screenshots>
+		<screenshot type="default">
+			<image></image>
+		</screenshot>
+	</screenshots>
+	<provides>
+		<id>lkt.desktop</id>
+	</provides>
+</component>
diff --git a/utils/desktop/lkt.desktop b/lkt/lkt.desktop
similarity index 94%
rename from utils/desktop/lkt.desktop
rename to lkt/lkt.desktop
index 43a0db42..ea639487 100644
--- a/utils/desktop/lkt.desktop
+++ b/lkt/lkt.desktop
@@ -2,7 +2,7 @@
 Version=1.0
 Type=Application
 Name=Lkt
-Icon=lektor
+Icon=lkt
 GenericName=lkt commnand line client
 Comment=lkt command line client
 Keywords=video;audio
diff --git a/lkt/lkt.png b/lkt/lkt.png
new file mode 100644
index 0000000000000000000000000000000000000000..e33521da3f8b9cdab4488e9f0c2f3d0f53d47da6
GIT binary patch
literal 4692
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=hEVFt%noI|q0=J1Z0v<)>xlq%tsQ
zOst(~>v1?hq}4yzbz)busH==oh&p$YtISp|*A)U;tzoi0alhDor6!4pyC2;8;KBK%
zs|SxphO>t|3jAR#EG`ZznJDz$n@cxo&xZ>6=XZ-M-rG5>m_9SD)Q4eK-t3hwF=tZ3
zkFE=65je(>Br#=X>KV@<p?zOV{qKg92hMwX|9kq^RhHe1j1w!SNiOr<<7l%tQ+m$#
z&ckaoRv&qO<gr@pgdY=McOB24!>z|{W1O=r`16s(q>UGjc}Z_xv{KMt&^^R=d5z-Z
zji)NRH;1j;^vw1rx3gt!>de<$+$J1Qnx^2`(xm03aoBB2*<2BBO{@OjKiXsWyXdvX
zs2UXMEMVf@^qT#D^Zm_RKW+5X*A!v5ikEqwEb`(OtCZ>SpLS()j&Taqu&w(tZGRAZ
znw{tRty@kAUf9kX6SLhUm4C+_#<qDpH>bpEdU&6B-uT`4*D{?8_1s_9R2FB?d;Epb
z<MNtG<_8Wc8iXx)Q#!xAeEa#g_vbzPQ^(NPQnbnA$<GJCcwtNOc6VX;4}uH!E}sk(
z;VkfoEM{QPQwCwiilz2tKtc8rPhVH|r;H+^CZbDX_U8eGBuiW)N}Tg^b5rw57@Uhz
z6H8K46v{J8G8EiBeFMT9`NSC*1hhR}977^F85IQXzi0I4bp3z(`v;(22vFq|U;y!-
zFuVW@IC5&hq`>t4?>89Q>=GEJ9ohlrgVe(SNMDwn2Urd!j%+qa9ZVd=2ARbKVt@e5
zLYM}SB{B>W5J@~FOg%^mvf;?$Fzv|lFfkTv3So|cDZ-`(CWp;XkbY#xqw`^UK{PxB
zkOfI$BRdYnt~#^;t{qtpB#6!jiLrnPd;nP!ddR@^A*+Fj5liC?0c4*LYZy!&DE*)V
zT#m=-0BnY!8;XlhisNxQ0GHv!h~slSdUO%(09-+c%R$7dM@fVrO~|eX6)GTrEl80q
zK-L3u5KIiD7nCKD)q~W)LV{6?!Sp{!09^q{3>loQZbRl`u#H=*FvMU2Fb5!)4Inv?
zohTsy(}0bZ2m)3EIDoWqI1U+vFuLV18LVmG<Nrr6d3cFNj3sbQBrvc#0Hhz}2oT0r
z)M7IqrXED&@+~%fU<cree||<eY<e)no}OI^7X#@b*3lqM7$E>ky~J7!x0M10h66xm
z!F&V?P7tUN^#fxthX8@DhfwapnG3$0I}WyL$&p3^Rzjp<>OnkYJulYX#i<{ZRxm;U
zTcLx~1RN4PMwSd9Obozq07w%)R}*6>C^V2m1fL$P4#1~@Qpcg24K9kYWkXm(MAtwH
zALLk25sj~0z!?J6_9-rh<8%PN$_1BU<cQ<Uh9JX0p@6LtIym<Vie2i0oLJSND8j+P
znFe6$K?MmmN5JIq(dNea;3}7_GypRg6cyyA2W*KOW-g4zNCVhh3vvW0)iKDyAobYH
zf>{isF&qGsz(#`%#TObdi+3Krh0?UcW)@5gB@H0Em{9PcS2Cbbg0%x-hQm6rFg`Y#
sYzH74hHf!Tju;0Ji~{6Pff-CqdPBhHFU5V)Yd~gty85}Sb4q9e0Bl&<u>b%7

literal 0
HcmV?d00001

diff --git a/utils/scripts/docker/package_appimages.bash b/utils/scripts/docker/package_appimages.bash
new file mode 100755
index 00000000..e4989c3a
--- /dev/null
+++ b/utils/scripts/docker/package_appimages.bash
@@ -0,0 +1,104 @@
+#!/usr/bin/env bash
+set -xe
+[ ! -f /build/.gitignore ] && {
+    echo "The appimage folder is not mounted in the docker"
+    exit 1
+}
+[ ! -d squashfs-root ] && {
+    echo "The appimage utilities where not deployed..."
+    exit 1
+}
+
+export ARCH=$(arch)
+export PATH="$PWD/squashfs-root/usr/bin:$PATH"
+export LD_LIBRARY_PATH="$PWD/squashfs-root/usr/lib:$LD_LIBRARY_PATH"
+export QMAKE=/usr/lib/qt6/bin/qmake6
+
+function join_by() {
+    local d=${1-} f=${2-}
+    if shift 2; then
+        printf %s "$f" "${@/#/$d}"
+    fi
+}
+
+function get_additional_libs() {
+    case $* in
+        *qt*) for LIB in /usr/lib/x86_64-linux-gnu/libQt6WaylandEglCompositorHwIntegration.so   \
+                         /usr/lib/x86_64-linux-gnu/libQt6WaylandEglClientHwIntegration.so       \
+                         /usr/lib/x86_64-linux-gnu/libQt6WaylandCompositor.so                   \
+                         /usr/lib/x86_64-linux-gnu/libQt6OpenGLWidgets.so                       \
+                         /usr/lib/x86_64-linux-gnu/libQt6OpenGL.so                              \
+                         /usr/lib/x86_64-linux-gnu/libQt6MultimediaWidgets.so                   \
+                         /usr/lib/x86_64-linux-gnu/libQt6Multimedia.so                          \
+                         /usr/lib/x86_64-linux-gnu/libQt6Concurrent.so                          \
+                         /usr/lib/x86_64-linux-gnu/libQt6WaylandClient.so                       \
+                         /usr/lib/x86_64-linux-gnu/libQt6XcbQpa.so                              \
+                         /usr/lib/x86_64-linux-gnu/libQt6EglFSDeviceIntegration.so              \
+                         /usr/lib/x86_64-linux-gnu/libQt6EglFsKmsGbmSupport.so                  \
+                         /usr/lib/x86_64-linux-gnu/libQt6EglFsKmsSupport.so                     ;
+        do
+            for FILE in ${LIB}*; do
+                echo -n " -l${FILE} "
+            done
+        done;;
+        *);;
+    esac
+}
+
+function deploy() {
+    local EXEC=${1,,}
+
+    local  EXTRA_QT_PLUGINS="concurrent;core;dbus;eglfsdeviceintegration;eglfskmssupport;gui;multimedia;multimediawidgets;"
+    local  EXTRA_QT_PLUGINS+="opengl;openglwidgets;waylandclient;waylandcompositor;widgets;xcbqpa;"
+    export EXTRA_QT_PLUGINS
+
+    local  EXTRA_PLATFORM_PLUGINS="libqxcb.so;libqeglfs.so;libqwayland-egl.so;libqwayland-generic.so;"
+    export EXTRA_PLATFORM_PLUGINS
+
+    local EXCLUDE_LIBS="libgdk_pixbuf libpango libcairo libgio libglib libgmodule libgobject libgthread"
+    local EXCLUDE_LIBS="-name *$(join_by "* -or -name *" $EXCLUDE_LIBS)*"
+
+    local QT_SRC=/usr/lib/x86_64-linux-gnu/qt6/plugins
+    local QT_DST=${EXEC^}/usr/plugins
+
+    # Will do most of the work
+    linuxdeploy -v1 --appdir ${EXEC^} -e target/release/${EXEC} \
+        -i ${EXEC}/${EXEC}.png -d ${EXEC}/${EXEC}.desktop       \
+        ${*:2} $(get_additional_libs $*)
+
+    # Handle aftermath things here, we force copy the qt plugins for wayland and remove unwanted
+    # libs... NOTE: For now we force the xcb platform because of troubles with wayland...
+    mkdir -p ${EXEC^}/apprun-hooks/
+    case ${*:2} in
+        *qt*)
+        echo "export QT_QPA_PLATFORM=xcb" > ${EXEC^}/apprun-hooks/force-xcb.sh
+        for PLUGIN in ${QT_SRC}/*; do
+            local PLUGIN=$(basename ${PLUGIN})
+            if [ ! -d ${QT_DST}/${PLUGIN} ]; then
+                cp -rf ${QT_SRC}/${PLUGIN} ${QT_DST}/${PLUGIN}
+            fi
+        done;;
+        *);;
+    esac
+    find ${EXEC^}/usr/lib/ -type f -and \( ${EXCLUDE_LIBS} \) -delete
+    cp LICENSE CHANGELOG.md CONTRIBUTING.md ${EXEC^}/
+    install -Dm644 ${EXEC}/${EXEC}.appdata.xml ${EXEC^}/usr/share/metainfo/${EXEC}.appdata.xml
+cat > ${EXEC^}/AppRun <<EOF
+#!/usr/bin/env bash
+set -e
+this_dir="\$(readlink -f "\$(dirname "\$0")")"
+for HOOK in "\$this_dir"/apprun-hooks/*; do
+    source "\$HOOK"
+done
+exec "\$this_dir"/AppRun.wrapped "$@"
+EOF
+
+    # Pack the AppImage
+    appimagetool -v --comp xz ${EXEC^}
+    mv ${EXEC^}-$(arch).AppImage /build/
+}
+
+deploy lkt
+deploy amadeus
+deploy lektord --plugin qt
+
diff --git a/utils/scripts/docker/package_zip.bash b/utils/scripts/docker/package_zip.bash
new file mode 100755
index 00000000..92553393
--- /dev/null
+++ b/utils/scripts/docker/package_zip.bash
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+set -xe
+[ ! -f /build/.gitignore ] && {
+    echo "The output folder is not mounted in the docker"
+    exit 1
+}
+
+cd $(readlink -f target/x86_64-pc-windows-gnu/release)
+
+mkdir -p lektor/platforms && cd lektor  # Prepare folders
+cp ../{lkt,amadeus,lektord}.exe .       # Copy the produced executables
+cp ../lektor_c.dll .                    # Copy the dll for lektord
+
+# Copy all the needed dll files
+for F in $(WINEPATH=/usr/x86_64-w64-mingw32/bin x86_64-w64-mingw32-ldd lektor_c.dll | grep -v "not found" | awk '{print $3}')
+do
+    cp "$F" .
+done
+chmod +x *.dll *.dll.*                                                           # Set DLL executable for linux, just in case
+cp /usr/x86_64-w64-mingw32/lib/qt6/plugins/platforms/qwindows.dll platforms/     # Copy the windows platform dll for Qt
+cp /usr/x86_64-w64-mingw32/lib/qt6/plugins/styles/qwindowsvistastyle.dll styles/ # Copy the style dll
+
+# Create the zip file
+cd ..
+zip lektor.zip lektor/* lektor/platforms/*
+mv lektor.zip /build/
diff --git a/utils/scripts/docker/prepare_workspace.bash b/utils/scripts/docker/prepare_workspace.bash
new file mode 100755
index 00000000..c504e7aa
--- /dev/null
+++ b/utils/scripts/docker/prepare_workspace.bash
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+set -e
+
+if [ "x$STAGE" = "x1" ]; then
+    cargo new --lib lektor_procmacros
+    cargo new --lib lektor_lib
+    cargo new --lib lektor_nkdb
+    cargo new --lib lektor_repo
+    cargo new --lib lektor_mpris
+    cargo new --lib kurisu_api
+    cargo new --lib lektor_payloads
+    cargo new --lib lektor_utils
+    cargo new lkt
+    cargo new lektord
+    cargo new amadeus
+    echo "" > lektor_procmacros/src/lib.rs
+    if [ -f $HOME/.cargo/env ]; then
+        echo "source $HOME.cargo/env" >> $HOME/.bashrc
+    fi
+else
+    find . -type f -exec touch -d "1990-01-01 00:00:00" {} \;
+    cargo build --release $*
+    rm -rf kurisu_api lektor_* lkt amadeus lektord
+fi
diff --git a/utils/scripts/docker/setup_base.bash b/utils/scripts/docker/setup_base.bash
new file mode 100755
index 00000000..bbdf53c6
--- /dev/null
+++ b/utils/scripts/docker/setup_base.bash
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+set -xe
+
+ARCH=$(arch)
+PKG_BASE="make libmpv-dev cmake clang clang-format manpages man-db"
+PKG_BACKPORT=""
+
+PKG_BACKPORT+=" qt6-base-dev qt6-declarative-dev qt6-multimedia-dev qt6-tools-private-dev"
+PKG_BACKPORT+=" qt6-tools-dev-tools qt6-tools-dev qt6-5compat-dev"
+PKG_BACKPORT+=" qt6-image-formats-plugins qt6-gtk-platformtheme qt6-base-abi libqt6xml6"
+PKG_BACKPORT+=" libqt6multimedia6 libqt6concurrent6 libqt6multimediawidgets6 "
+PKG_BACKPORT+=" libqt6opengl6 libqt6openglwidgets6 libqt6widgets6"
+PKG_BACKPORT+=" qt6-translations-l10n qt6-l10n-tools"
+
+PKG_BACKPORT+=" qt6-wayland-dev qt6-wayland qt6-wayland-dev-tools"
+PKG_BACKPORT+=" libqt6waylandclient6 libqt6waylandcompositor6 libqt6waylandeglclienthwintegration6"
+PKG_BACKPORT+=" libqt6waylandeglcompositorhwintegration6 libqt6wlshellintegration6"
+
+PKG_BACKPORT+=" qt6-qpa-plugins"
+
+function appimage_setup() {
+    local APPIMAGE=$(basename "$1")
+    wget "$1"
+    chmod +x ${APPIMAGE}
+    ./${APPIMAGE} --appimage-extract
+    rm -rf ${APPIMAGE}
+}
+
+echo "deb     http://deb.debian.org/debian bullseye-backports main contrib non-free" >> /etc/apt/sources.list
+echo "deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free" >> /etc/apt/sources.list
+
+apt update
+apt upgrade -y
+apt -y install $PKG_BASE
+apt -y install -t bullseye-backports $PKG_BACKPORT
+rm -rf /var/cache/
+
+appimage_setup \
+    https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$ARCH.AppImage
+
+appimage_setup \
+    https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-$ARCH.AppImage
+
+appimage_setup \
+    https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-$ARCH.AppImage
diff --git a/utils/scripts/docker/setup_cross.bash b/utils/scripts/docker/setup_cross.bash
new file mode 100755
index 00000000..a56aeffc
--- /dev/null
+++ b/utils/scripts/docker/setup_cross.bash
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+set -xe
+
+PKG_BASE="imagemagick make ninja git binutils patch base-devel unzip protobuf"
+PKG_MINGW="mingw-w64-binutils mingw-w64-crt mingw-w64-gcc mingw-w64-headers mingw-w64-winpthreads"
+
+AUR_BOOTSTRAP_MINGW="mingw-w64-x264-bootstrap mingw-w64-headers-bootstrap mingw-w64-freetype2-bootstrap mingw-w64-cairo-bootstrap "
+AUR_BOOTSTRAP_MINGW+="mingw-w64-cmake mingw-w64-extra-cmake-modules mingw-w64-make mingw-w64-configure mingw-w64-meson mingw-w64-pkg-config "
+
+AUR_MINGW="mingw-w64-mpv mingw-w64-bzip2 mingw-w64-expat mingw-w64-fontconfig mingw-w64-freeglut mingw-w64-freetype2 "
+AUR_MINGW+="mingw-w64-libdbus mingw-w64-libiconv mingw-w64-libjpeg-turbo mingw-w64-libpng mingw-w64-libtiff mingw-w64-libxml2 "
+AUR_MINGW+="mingw-w64-openssl mingw-w64-openjpeg mingw-w64-openjpeg2 mingw-w64-pcre mingw-w64-pdcurses mingw-w64-protobuf "
+AUR_MINGW+="mingw-w64-readline mingw-w64-sdl2 mingw-w64-termcap mingw-w64-tools mingw-w64-zlib mingw-w64-gettext "
+
+AUR_QT_MINGW="clang qt6-tools mingw-w64-qt6-base mingw-w64-qt6-base-static mingw-w64-qt6-5compat "
+AUR_QT_MINGW+="mingw-w64-qt6-imageformats mingw-w64-qt6-multimedia mingw-w64-qt6-shadertools "
+AUR_QT_MINGW+="mingw-w64-qt6-svg mingw-w64-qt6-tools mingw-w64-qt6-translations "
+
+# Base system
+pacman-key --init
+pacman-key --populate
+
+pacman -Syu --noconfirm --noprogressbar archlinux-keyring pacman
+pacman-db-upgrade
+
+pacman -Syu --noconfirm --noprogressbar ca-certificates
+trust  extract-compat
+pacman -Syu --noconfirm --noprogressbar --needed ${PKG_BASE}
+
+cat >> /etc/pacman.conf << EOF
+[multilib]
+Include = /etc/pacman.d/mirrorlist
+EOF
+
+pacman -Syu --noconfirm --noprogressbar --needed ${PKG_MINGW}
+useradd -m -d /home/devel -u 1000 -U -G users,tty -s /bin/bash devel
+echo "devel ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+
+# AUR + Rust
+su -c bash - devel << EOF
+    set -xe
+    cd /home/devel
+
+    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o rustup.sh
+    chmod +x rustup.sh
+    ./rustup.sh -y
+    source ~/.cargo/env
+    rustup target add x86_64-pc-windows-gnu
+
+    git clone https://aur.archlinux.org/yay.git --depth 1
+    (cd yay && makepkg -si --noconfirm --noprogressbar)
+    yay -Syu --answerdiff=None --verbose --noconfirm $AUR_BOOTSTRAP_MINGW
+    (cd mingw-w64-shaderc && makepkg -si --noconfirm --noprogressbar)
+    yay -Syu --answerdiff=None --verbose --noconfirm mingw-w64-glslang
+    yay -Syu --answerdiff=None --verbose --noconfirm $AUR_MINGW_2
+    yay -Syu --answerdiff=None --noconfirm $AUR_MISC $AUR_MINGW $AUR_QT_MINGW
+    go clean -cache
+EOF
+
+# Clear cache to reduce image size
+rm -rf /var/cache/pacman/pkg/ /var/lib/pacman/ /etc/pacman.d/gnupg/
+rm -rf /home/devel/yay /home/devel/.cache/yay
+rm /home/devel/rustup.sh
diff --git a/utils/scripts/docker/touch_files.bash b/utils/scripts/docker/touch_files.bash
new file mode 100755
index 00000000..ecf319a7
--- /dev/null
+++ b/utils/scripts/docker/touch_files.bash
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+set -e
+shopt -s globstar
+
+[ ! -f /src/.gitignore ] && {
+    echo "The source folder is not mounted in the docker"
+    exit 1
+}
+
+# Remove the thing we used to setup the build cache...
+rm -rf kurisu_api lektor_* lkt amadeus lektord
+
+# Get the sources...
+for THING in /src/*; do
+    cp -rf ${THING} .
+done
-- 
GitLab