Files
o3de-flatpak/README.md
T
pc-heini 583c81ed51 Fix editable-install patch for 26.05 + unblock icon in unprivileged build
The previous patch matched a development-branch variable that does not
exist in release 2605.0, so the warning fired and the editable install was
not patched. In 2605.0 the -e is hardcoded in the pip command
("pip install -e ${package_folder_path}"); strip the -e there instead.

Also, flatpak build-export validates exported app icons in a bwrap sandbox,
which fails in an unprivileged container. Keep the icon inside the app (for
the running window/taskbar) but remove it from build-dir/export so export
skips validation. Host menu icon stays generic; build needs no privileges.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 12:17:11 +02:00

7.8 KiB
Raw Blame History

O3DE Flatpak

Repackage the official Open 3D Engine Linux release as a Flatpak so it can be installed on any distribution — not only Debian/Ubuntu.

A Gitea Actions workflow checks daily for a new O3DE release, builds the Flatpak, and publishes it as a static OSTree Flatpak repository on the pages branch of this repo. You add that as a Flatpak remote and install / update like any other app.

Status: community / unofficial. O3DE is a large application (~1518 GB installed); building and hosting it is heavy. Treat this as best-effort.


Installing (end users)

# Flathub provides the runtime O3DE needs
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

# Add this repo (replace <owner> with the Gitea account that owns the repo)
flatpak remote-add --if-not-exists o3de \
  https://gitea.pc-heini.de/<owner>/o3de-flatpak/raw/branch/pages/o3de.flatpakrepo

flatpak install o3de org.o3de.O3DE
flatpak run org.o3de.O3DE

Later updates:

flatpak update org.o3de.O3DE

The repo is currently unsigned (no GPG). Flatpak will add it with GPG verification disabled. See Signing below to harden this.


How it works

File Purpose
scripts/make-flatpak.sh The build. Unpacks the official o3de_*.deb into /app, bakes in Python, and exports an OSTree repo using flatpak build-init/build-finish/build-export — no flatpak-builder, no bubblewrap, no privileged container.
o3de-wrapper.sh Entry point. Finds the versioned o3de Project Manager binary inside the sandbox and sets LD_LIBRARY_PATH.
org.o3de.O3DE.desktop Desktop entry under the Flatpak app-id.
org.o3de.O3DE.metainfo.xml AppStream metadata (version stamped at build time).
scripts/get-latest-version.sh Resolves the latest .deb URL, version, and SHA-256 from o3debinaries.org.
scripts/build.sh Download + build + test the Flatpak locally (wraps make-flatpak.sh).
org.o3de.O3DE.yaml Equivalent flatpak-builder manifest — kept as an alternative for builders that have a privileged/bwrap-capable environment. Not used by CI.
.gitea/workflows/build-flatpak.yml CI: detect new version → build → publish to pages → tag vX.Y.Z.

The engine ships as a Debian package at a predictable URL (https://o3debinaries.org/main/Latest/Linux/o3de_<ver>.deb). The build extracts it (ar + tar) and copies the payload into the Flatpak's /app. The version directory inside the .deb changes every release, so the wrapper discovers the executable at runtime rather than hard-coding a path.


CI requirements (Gitea Actions)

The workflow targets a self-hosted act_runner. Because O3DE is large:

  • Disk: budget 60 GB+ free. The build needs roughly 23× the installed size (extracted payload in build-dir + a copy committed into the OSTree repo/). The job deletes build-dir before publishing to cut peak usage, but it can still be tight. If builds fail on space, that's the first thing to check.
  • No privileged container required. The build avoids flatpak-builder/bwrap and uses flatpak build-init/build-finish/build-export, which only touch files and the OSTree repo. A plain unprivileged job container works.
  • Runner label: the job uses runs-on: ubuntu-latest. Change it if your runner is registered with a different label.
  • Token: publishing force-pushes the pages branch and creates a vX.Y.Z tag. The auto-provided GITHUB_TOKEN (with contents: write) usually suffices. If your instance restricts it, create a Personal Access Token with repo write access and add it as a secret named PUBLISH_TOKEN — the workflow prefers it automatically.

Trigger it manually from the Gitea Actions UI (workflow_dispatch, with an optional force rebuild), or let the daily cron run it. It only rebuilds when the upstream version has no matching vX.Y.Z tag yet, so reruns are cheap no-ops.


Building locally

# flatpak + cmake (cmake is used by O3DE's get_python.sh) + curl
sudo apt install flatpak cmake      # or your distro's equivalent
./scripts/build.sh

Then install from the local repo/ and run:

flatpak remote-add --user --no-gpg-verify o3de-local repo
flatpak install --user o3de-local org.o3de.O3DE
flatpak run org.o3de.O3DE

The first iteration publishes an unsigned repo for simplicity. To sign:

  1. Generate a key: gpg --quick-gen-key "O3DE Flatpak" default default never
  2. Export the public key and add GPGKey=<base64> to the generated .flatpakrepo.
  3. Pass --gpg-sign=<KEYID> to both flatpak-builder and build-update-repo, and provide the private key to CI via a secret. Until then, users add the remote with GPG verification disabled.

Caveats & things to verify

These were confirmed by inspecting the v26.05 package (opt/O3DE/26.05/…):

  • Layout is confirmed for now: the package installs everything under /opt/O3DE/<ver>/, with the launcher at bin/Linux/profile/Default/o3de and ~270 .so files beside it (hence the wrapper's LD_LIBRARY_PATH). If a future release moves things, adjust o3de-wrapper.sh and the manifest.
  • Runs against org.freedesktop.Sdk, not Platform. O3DE's package dependencies are a build toolchain (clang/ninja/cmake/pkg-config) because the engine compiles project code at runtime. Those live in the SDK. Users therefore pull the SDK runtime (larger than Platform) on install — Flatpak does this automatically from Flathub.
  • Python is per-user, not baked in. On first launch O3DE downloads its Python runtime and builds a venv under ~/.o3de (writable), pip-installing its deps there. The build does not bundle Python — the venv is keyed to the user's home path, so it can only be created at runtime.
  • The editable-install patch. O3DE installs its own o3de CLI with pip install -e, which writes an egg-info next to the source under read-only /app and fails. The build patches cmake/LYPython.cmake to drop the -e, so it's a normal install (built in a temp dir, landing in the writable ~/.o3de venv). If a future O3DE release changes that pip command, the build prints a warning and Python setup will fail at runtime — that's the line to re-check.
  • Other runtime writes into the install tree may still fail. Anything else O3DE tries to generate inside /opt/O3DE/... at runtime (e.g. certain per-gem Python deps, or the engine-level asset cache) hits the read-only /app. Project data lives in your writable home dir, so normal project work should be fine; this is the main remaining open risk.
  • Launcher icon. Shipped as org.o3de.O3DE.png (the .deb itself has only in-editor asset icons). It's kept inside the app so the running window/taskbar shows it, but removed from the exported set because flatpak build-export validates exported icons in a bwrap sandbox that fails in an unprivileged container. Consequence: the host menu launcher icon is generic. A privileged runner would let us export it properly.
  • GPU / drivers: the renderer needs working GPU access. The manifest grants --device=dri/--device=all; on some setups you may also want the matching GPU driver extension from Flathub.
  • Sandbox filesystem: --filesystem=home lets the Project Manager create and open projects under your home directory. Tighten or widen to taste.
  • Hosting via raw branch URLs works because Flatpak fetches individual files (summary, config, objects/…). Gitea serves these from the pages branch. If you later put a real static web host in front of it, just change Url= in the .flatpakrepo.

Not affiliated with or endorsed by the Open 3D Foundation. O3DE is licensed under Apache-2.0 / MIT.