1
0
aki b0479bfbf4 feat: Implement Flatpak build system using flatpak-builder in Docker
This commit replaces the previous multi-distribution Docker build system with a unified Flatpak build process executed inside a Docker container. This is the intended final architecture for building Aseprite bundles.

**Key Changes:**

*   **Transition to Flatpak:** The core build logic now uses `flatpak-builder` and a Flatpak manifest (`com.aseprite.Aseprite.yaml`) to compile Aseprite and its dependencies against a standard Flatpak SDK runtime.
*   **Unified Docker Environment:** Replaced distribution-specific `Dockerfile.<distro>` files with a single `Dockerfile` that sets up a consistent environment containing `flatpak-builder` and the necessary Flatpak SDK.
*   **Simplified Makefile:** Removed OS detection logic and multi-distro targets. The Makefile now orchestrates:
    1.  Running `prepare_sources.sh` on the host (still responsible for reliable source fetching/syncing).
    2.  Building the single Flatpak builder Docker image.
    3.  Running `flatpak-builder` inside a *privileged* container (required for `flatpak-builder` sandboxing) to perform the actual build.
    4.  Running `flatpak build-bundle` inside the container.
    5.  Extracting the final `.flatpak` bundle from the container to `./target/aseprite.flatpak`.
*   **Updated .gitignore:** Added `build/`, `target/`, `*.flatpak`, and `*.log` to ignore Flatpak build directories, output bundles, and logs. Removed the old `dependencies` ignore pattern.
*   **Prepare Sources Update:** Modified `prepare_sources.sh` to explicitly initialize `depot_tools` on the host, as this is required before sources are copied into the Flatpak build environment for `gn` usage.
*   **Removal of Old Files:** Deleted `Dockerfile.<distro>`, `Dockerfile.debian`, `Dockerfile.fedora`, `Dockerfile.arch` (multi-distro Dockerfiles), and the original generic `Dockerfile` and `docker-compose.yml`.

**Rationale:**

This refactor moves to the planned final architecture. Building within a Flatpak SDK provides a highly consistent environment independent of the host Linux distribution. The output is a portable `.flatpak` bundle, simplifying distribution and runtime compatibility compared to dynamically linking against varied host libraries. While `prepare_sources.sh` on the host still handles the initial (and potentially rate-limited) source fetching, the subsequent build process is significantly standardized and more reliable.

This architecture is now the **forward-maintained** build method.
2025-05-06 17:02:01 +08:00

147 lines
8.4 KiB
Markdown

# Docker Aseprite Flatpak Builder
This repository provides a Docker-based environment to compile Aseprite into a portable Flatpak bundle. It uses `flatpak-builder` inside a containerized environment for consistency and leverages a robust host-side script to prepare sources reliably.
## Requirements
* Docker (BuildKit backend enabled, which is default in modern versions)
* Make
* Git
* Curl
* Host kernel with `fuse` module loaded (common on most desktop Linux systems).
* Sufficient disk space and RAM for source code and compilation.
* **CPU with AVX support:** The compiled binary requires a CPU supporting the AVX instruction set (generally CPUs from 2011/Sandy Bridge/Bulldozer onwards).
> [!IMPORTANT]
> The Docker build process requires elevated privileges (`--privileged`) to allow `flatpak-builder`'s sandboxing (bubblewrap) to function correctly. The `Makefile` handles adding this flag automatically. Ensure your environment allows privileged Docker builds.
## Quick Start
1. **Clone:**
```bash
git clone <repository-url>
cd docker-aseprite-linux
```
2. **Build:**
```bash
make build
```
3. **Run:** Find the compiled Flatpak bundle in `./output/aseprite.flatpak`. You can install it using:
```bash
flatpak install ./output/aseprite.flatpak
```
## Build Process Explained
The `make build` command performs the following steps:
1. **Prepare Sources (via `./prepare_sources.sh`):**
* This script runs on your **host machine** first to reliably acquire and prepare the source code.
* Clones `depot_tools`, Skia, and Aseprite source code into the `./src` directory if they don't exist. See the script for specific versions.
* Runs Skia's `git-sync-deps` command locally with **automatic retries** (default: 3 attempts, configurable via `PREPARE_RETRIES`) to download Skia's internal build dependencies (like the `gn` tool) and mitigate failures from network issues or rate limiting.
* Includes an **`--check-integrity`** flag for advanced validation and resetting of source repositories (see Advanced Usage).
* This step isolates the often failure-prone network operations and source state management before the main build begins.
2. **Build Docker Image (using `Dockerfile`):**
* Builds a single Docker image (`aseprite-flatpak-builder`) based on Debian Slim.
* Installs `flatpak`, `flatpak-builder`, and the required Freedesktop Platform/SDK (e.g., 23.08).
* **Copies** the prepared sources from `./src` on the host into `/sources` inside the container. This leverages Docker's layer caching for the source code.
* Copies the Flatpak manifest `com.aseprite.Aseprite.yaml`.
* Runs `flatpak-builder` inside the container using the manifest and the copied sources. This compiles Skia and Aseprite within the consistent Flatpak SDK environment.
* Bundles the result into an `aseprite.flatpak` file inside the container.
* **Note:** This step runs with `--privileged` to allow `flatpak-builder`'s sandboxing mechanisms to work.
3. **Extract Flatpak Bundle:** Copies the final `aseprite.flatpak` file from the container's `/output` directory to `./output` on your host machine.
## Troubleshooting
### Build Failures
* **Resource Exhaustion:** Compiling Skia and Aseprite requires significant RAM and disk space. Ensure your system (and Docker) has adequate resources allocated.
* **Network Issues / Rate Limiting (during `prepare_sources.sh`):**
* Ensure you have a stable internet connection. Check for proxy issues if applicable.
* The Skia sync step (`git-sync-deps`) might hit rate limits (HTTP 429 errors) from Google's servers. The script automatically retries (default: 3 total attempts). If it consistently fails, wait a while before trying again, or increase the number of retries via the `PREPARE_RETRIES` environment variable (e.g., `PREPARE_RETRIES=5 make build`).
* **`flatpak-builder` Errors (during Docker build):**
* **Manifest Errors:** Check `com.aseprite.Aseprite.yaml` for syntax errors or incorrect paths/commands.
* **SDK Issues:** Ensure the SDK version specified in the manifest and Dockerfile is available and installs correctly.
* **Sandbox/Bubblewrap Errors (e.g., FUSE issues):**
* Verify the `docker build` command is running with `--privileged` (handled by the Makefile).
* Ensure the `fuse` kernel module is loaded on your **host system** (`lsmod | grep fuse`). If not, try `sudo modprobe fuse`.
* Check Docker/BuildKit logs for specific bubblewrap (`bwrap`) errors.
* **Compilation Errors:** Check the detailed build log output from Docker (during the `flatpak-builder` step) for C++/CMake/Ninja errors. These could indicate issues with the source code versions, compiler compatibility, or missing dependencies within the Flatpak SDK.
### Runtime Errors (After Installing `.flatpak`)
* **`Illegal instruction`**: This typically means the compiled binary is trying to use CPU instructions not supported by your processor. This build requires a CPU with **AVX** support.
* **Missing Portals / File Dialog Issues:** Ensure you have the necessary Flatpak portals installed on your host system (e.g., `xdg-desktop-portal`, `xdg-desktop-portal-gtk` or `-kde`, etc.) for features like file choosers to work correctly.
* **Permission Issues:** If Aseprite cannot save files or access expected locations, review the `finish-args` in `com.aseprite.Aseprite.yaml`. The current `--filesystem=home` is broad; more restrictive permissions might require specific portal interactions.
## Advanced Usage
The `make build` command automatically runs `./prepare_sources.sh` without any special flags. If you need to control the source preparation step (e.g., force a check integrity and reset), you can run the script manually *before* running `make build`.
### Running `prepare_sources.sh` Manually
* **Check Source Integrity & Reset:** Runs `git fsck`, fetches updates, checks out the exact target commit/tag, and resets submodules. **Warning:** This performs potentially network-intensive operations and modifies local source directories to match the expected state.
```bash
./prepare_sources.sh --check-integrity
# If successful, proceed with make build
make build
```
* **Set Sync Retries:** Control the number of retries for the Skia `git-sync-deps` step (default is 2 retries, total 3 attempts).
```bash
PREPARE_RETRIES=5 ./prepare_sources.sh
make build
```
### Passing Options via `make`
* **Set Sync Retries via `make`:**
```bash
PREPARE_RETRIES=5 make build
```
* **Force Source Reset via `make`:** The recommended way to ensure sources are reset and prepared fresh is to run `make clean` followed by `make build`.
```bash
make clean && make build # Clean output, then build (includes fresh source prep)
```
### Clean Up
To remove the build output (`./output`):
```bash
make clean
```
Note: This does *not* remove the downloaded sources in `./src`. To remove those as well, manually delete the `./src` directory or run `rm -rf ./src`.
## Architecture Notes
This project uses a hybrid approach combining a robust host-side source preparation script with a containerized Flatpak build process:
1. **Host-Side Source Prep (`prepare_sources.sh`):** Handles the potentially fragile steps of cloning, syncing dependencies (with retries), and ensuring the correct state of source code repositories locally in `./src`.
2. **Docker Build (`Dockerfile`):**
* Creates a consistent build environment using Debian and the standard Flatpak SDK.
* Copies the locally prepared sources into the container, leveraging Docker's layer caching.
* Runs `flatpak-builder` using `com.aseprite.Aseprite.yaml` to compile Aseprite against the SDK libraries and the copied sources. Requires `--privileged` for sandboxing.
3. **Flatpak Manifest (`com.aseprite.Aseprite.yaml`):** Defines the application metadata, permissions, and the sequence of build steps (depot\_tools setup, Skia compile, Aseprite compile, metadata installation) executed by `flatpak-builder`.
4. **Makefile:** Orchestrates the process: `prepare_sources.sh` -> `docker build --privileged` -> extract `.flatpak`.
This architecture aims for:
* **Reliability:** By handling source fetching/syncing with retries outside the main build.
* **Consistency:** By using the standard Flatpak SDK inside Docker.
* **Portability:** By producing a `.flatpak` bundle that should run across different Linux distributions.
* **Maintainability:** By consolidating the build logic into a single Dockerfile and Flatpak manifest.
## License
[MIT License](LICENSE)