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.
This commit is contained in:
2025-05-06 17:02:01 +08:00
parent 2b47036cc8
commit b0479bfbf4
7 changed files with 403 additions and 666 deletions

143
Makefile
View File

@@ -1,32 +1,13 @@
# --- OS Detection ---
# Attempt to detect host OS family. Fallback to 'arch'.
# This logic checks /etc/os-release for ID or ID_LIKE fields.
# Use $(strip ...) to remove potential leading/trailing whitespace from shell output.
DETECTED_DISTRO := $(strip $(shell \
if [ -f /etc/os-release ]; then \
. /etc/os-release; \
if echo "$$ID$$ID_LIKE" | grep -q -e arch; then \
echo arch; \
elif echo "$$ID$$ID_LIKE" | grep -q -e debian -e ubuntu; then \
echo debian; \
elif echo "$$ID$$ID_LIKE" | grep -q -e fedora; then \
echo fedora; \
else \
echo arch; \
fi; \
else \
echo arch; \
fi \
))
# Set default TARGET_DISTRO based on detection, allowing user override
TARGET_DISTRO ?= $(DETECTED_DISTRO)
# --- Configuration ---
IMAGE_NAME := docker-aseprite-${TARGET_DISTRO}
DOCKERFILE := Dockerfile.${TARGET_DISTRO}
OUTPUT_DIR := ${PWD}/output
TARGET_DIR_IN_IMAGE := /target/aseprite/build/bin
# Uses a single Dockerfile with flatpak-builder inside
IMAGE_NAME := aseprite-flatpak-builder
DOCKERFILE := Dockerfile
TARGET_DIR := ${PWD}/target
OUTPUT_FILE := ${TARGET_DIR}/aseprite.flatpak
BUILD_DIR := ${PWD}/build
SRC_DIR := ${PWD}/src
FLATPAK_STATE_DIR := ${PWD}/flatpak-state
FLATPAK_CACHE_DIR := ${PWD}/flatpak-cache
# --- Main Targets ---
# Default target
@@ -36,59 +17,79 @@ all: build
# Use .PHONY to ensure it always runs if called directly
.PHONY: prepare-sources
prepare-sources:
@echo "--- Preparing sources ---"
@echo "--- Preparing sources using prepare_sources.sh ---"
@./prepare_sources.sh
# Build the Docker image for the target distribution
# Depends on sources being ready (though prepare-sources isn't a file dependency)
# Build the Docker image which runs flatpak-builder inside
# Implicitly depends on sources being ready after prepare-sources runs
.PHONY: build-image
build-image:
# --- DEBUGGING ---
@echo "DEBUG: TARGET_DISTRO='${TARGET_DISTRO}'"
@echo "DEBUG: DOCKERFILE='${DOCKERFILE}'"
# --- END DEBUGGING ---
ifeq (,$(wildcard ${DOCKERFILE}))
$(error Dockerfile for target distribution '${TARGET_DISTRO}' (${DOCKERFILE}) not found)
endif
@echo "--- Building Docker image (${IMAGE_NAME}) using ${DOCKERFILE} ---"
@echo "--- Building Aseprite Flatpak builder image (${IMAGE_NAME}) ---"
@docker build -t ${IMAGE_NAME} -f ${DOCKERFILE} .
# Extract the compiled binary from the image
# Depends on the image being built
.PHONY: extract-binary
extract-binary: build-image
@echo "--- Extracting Aseprite binary from ${IMAGE_NAME} ---"
@mkdir -p ${OUTPUT_DIR}/bin
@CONTAINER_ID=$$(docker create ${IMAGE_NAME}) && \
docker cp "$${CONTAINER_ID}:${TARGET_DIR_IN_IMAGE}/." "${OUTPUT_DIR}/bin/" && \
docker rm "$${CONTAINER_ID}" > /dev/null
@echo "Aseprite binary extracted to ${OUTPUT_DIR}/bin"
# Run flatpak-builder inside a privileged container
# Create persistent cache directories to improve caching
.PHONY: run-flatpak-builder
run-flatpak-builder:
@echo "--- Running flatpak-builder inside container ---"
@mkdir -p ${BUILD_DIR} ${FLATPAK_STATE_DIR} ${FLATPAK_CACHE_DIR}
@docker run \
--rm \
--privileged \
--device /dev/fuse \
-v ${SRC_DIR}:/sources:ro \
-v ${BUILD_DIR}:/build \
-v ${FLATPAK_STATE_DIR}:/root/.local/share/flatpak-builder \
-v ${FLATPAK_CACHE_DIR}:/root/.cache/flatpak-builder \
-v ${PWD}/com.aseprite.Aseprite.yaml:/build/com.aseprite.Aseprite.yaml:ro \
-w /build \
${IMAGE_NAME} \
sh -c "flatpak-builder --disable-rofiles-fuse --state-dir=/root/.local/share/flatpak-builder --ccache --force-clean build-dir com.aseprite.Aseprite.yaml --repo=repo"
# Main build target: Prepare sources, build image, extract binary for selected distro
# Create the Flatpak bundle from the repo built in the previous step
.PHONY: create-bundle
create-bundle: run-flatpak-builder
@echo "--- Creating Flatpak bundle ---"
@docker run \
--rm \
--privileged \
--device /dev/fuse \
-v ${BUILD_DIR}:/build \
-w /build \
${IMAGE_NAME} \
sh -c "flatpak build-bundle repo aseprite.flatpak com.aseprite.Aseprite"
# Copy the final bundle from the intermediate directory to the output directory
.PHONY: extract-flatpak
extract-flatpak: create-bundle
@echo "--- Copying Flatpak bundle to target directory ---"
@mkdir -p ${TARGET_DIR}
@cp ${BUILD_DIR}/aseprite.flatpak ${OUTPUT_FILE}
@echo "Aseprite Flatpak bundle is in ${OUTPUT_FILE}"
# Prepare build target: Prepare sources, build Docker image
.PHONY: prepare
prepare: prepare-sources build-image
@echo "--- Prepare complete ---"
# Main build target: Run builder, create bundle, extract
.PHONY: build
build: prepare-sources build-image extract-binary
@echo "--- Build complete for ${TARGET_DISTRO} ---"
@echo "Aseprite binary is in ${OUTPUT_DIR}/bin"
# --- Specific Distribution Targets ---
.PHONY: build-arch build-debian build-fedora
# Build for Arch Linux (default if not detected otherwise)
build-arch:
$(MAKE) build TARGET_DISTRO=arch
# Build for Debian/Ubuntu based systems
build-debian:
$(MAKE) build TARGET_DISTRO=debian
# Build for Fedora based systems
build-fedora:
$(MAKE) build TARGET_DISTRO=fedora
build: run-flatpak-builder create-bundle extract-flatpak
@echo "--- Build complete ---"
# --- Utility Targets ---
# Clean up downloaded sources and output directory
# Clean up the output and intermediate build directories
.PHONY: clean
clean:
@echo "--- Cleaning up ---"
@rm -rf ./src
@rm -rf ${OUTPUT_DIR}
@rm -rf ${TARGET_DIR}
@rm -rf ${BUILD_DIR}
@echo "Cleanup complete."
# Deep clean - removes all caches as well
.PHONY: deep-clean
deep-clean: clean
@echo "--- Deep cleaning (including caches) ---"
@rm -rf ${FLATPAK_STATE_DIR}
@rm -rf ${FLATPAK_CACHE_DIR}
@echo "Deep cleanup complete."