f4d2dddd02
On first launch O3DE pip-installs its 'o3de' CLI with 'pip install -e'
(editable), which writes an egg-info next to the source under read-only
/app and fails ([Errno 30] Read-only file system), leaving the venv broken
("unable to install O3DE's built-in Python").
- Patch cmake/LYPython.cmake at build time to force a normal (non-editable)
install, which builds in a temp dir and lands in the writable ~/.o3de venv.
- Drop the build-time get_python "bake": the venv is per-user (keyed to
$HOME), so it can only be created at runtime; baking under a throwaway
build HOME did nothing. Speeds up CI; removes cmake/python3 build deps and
the network build-arg.
- Add a real launcher icon (org.o3de.O3DE.png).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
161 lines
7.5 KiB
Markdown
161 lines
7.5 KiB
Markdown
# O3DE Flatpak
|
||
|
||
Repackage the official [Open 3D Engine](https://o3de.org/) 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](https://ostreedev.github.io/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 (~15–18 GB
|
||
> installed); building and hosting it is heavy. Treat this as best-effort.
|
||
|
||
---
|
||
|
||
## Installing (end users)
|
||
|
||
```sh
|
||
# 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:
|
||
|
||
```sh
|
||
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 2–3× 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
|
||
|
||
```sh
|
||
# 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:
|
||
|
||
```sh
|
||
flatpak remote-add --user --no-gpg-verify o3de-local repo
|
||
flatpak install --user o3de-local org.o3de.O3DE
|
||
flatpak run org.o3de.O3DE
|
||
```
|
||
|
||
---
|
||
|
||
## Signing (recommended hardening)
|
||
|
||
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 use a normal
|
||
(non-editable) install, which builds in a temp dir and lands in the `~/.o3de`
|
||
venv. If a future O3DE release renames that variable, 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** is shipped as `org.o3de.O3DE.png` (the `.deb` itself contains
|
||
only in-editor asset icons, none suitable as an app icon).
|
||
- **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.*
|