From f4d2dddd02a792824492908af5c122a68ff07987 Mon Sep 17 00:00:00 2001 From: pc-heini Date: Mon, 15 Jun 2026 12:02:41 +0200 Subject: [PATCH] Fix read-only /app failure + add app icon 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 --- .gitea/workflows/build-flatpak.yml | 4 +--- README.md | 29 +++++++++++++++++------------ org.o3de.O3DE.png | Bin 0 -> 8507 bytes org.o3de.O3DE.yaml | 26 ++++++++++---------------- scripts/make-flatpak.sh | 21 +++++++++++++-------- 5 files changed, 41 insertions(+), 39 deletions(-) create mode 100644 org.o3de.O3DE.png diff --git a/.gitea/workflows/build-flatpak.yml b/.gitea/workflows/build-flatpak.yml index 6c27d379e..3f55e0b8b 100644 --- a/.gitea/workflows/build-flatpak.yml +++ b/.gitea/workflows/build-flatpak.yml @@ -26,11 +26,9 @@ jobs: - name: Install build dependencies run: | apt-get update - # cmake + python3: O3DE's get_python.sh (run on the host, not in the - # sandbox) uses cmake to fetch its Python runtime. DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ ca-certificates curl git jq xz-utils zstd binutils tar \ - flatpak cmake python3 + flatpak # Done as a plain git clone instead of actions/checkout@v4: the bare # ubuntu image has no Node.js, so JavaScript actions fail with exit 127. diff --git a/README.md b/README.md index 4aa75d254..1c68e3d05 100644 --- a/README.md +++ b/README.md @@ -127,18 +127,23 @@ These were confirmed by inspecting the v26.05 package (`opt/O3DE/26.05/…`): 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 baked in at build time.** O3DE normally downloads its Python runtime - into its own install tree on first use, but that tree is read-only inside a - Flatpak. The manifest runs `python/get_python.sh` during the build (with network - access) so Python is part of the immutable image. **This is the most likely step - to need tweaking** — verify it on the first real CI build. -- **Runtime writes into the install tree may still fail.** Anything O3DE tries to - `pip install` or generate *inside* `/opt/O3DE/...` at runtime (e.g. per-gem - Python deps when building certain projects) will hit the read-only `/app`. Base - project building should work; exotic gems may not. This is the main open risk. -- **No launcher icon yet.** The `.deb` ships only in-editor asset icons, so the - desktop entry uses a generic icon. Drop a real O3DE logo into the repo and - install it in the manifest to fix this. +- **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. diff --git a/org.o3de.O3DE.png b/org.o3de.O3DE.png new file mode 100644 index 0000000000000000000000000000000000000000..a9b9d0e0b187b683821fcc24843ba5b6d3844bc7 GIT binary patch literal 8507 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 literal 0 HcmV?d00001 diff --git a/org.o3de.O3DE.yaml b/org.o3de.O3DE.yaml index 11fe19524..0956020cc 100644 --- a/org.o3de.O3DE.yaml +++ b/org.o3de.O3DE.yaml @@ -28,11 +28,6 @@ finish-args: modules: - name: o3de buildsystem: simple - # The Python bootstrap step (below) downloads O3DE's Python runtime into the - # install tree, so this module needs network access during the build. - build-options: - build-args: - - --share=network build-commands: # The .deb is an `ar` archive containing data.tar.{gz,xz,zst}. - ar x o3de.deb @@ -42,25 +37,22 @@ modules: # is kept for robustness in case a future release adds desktop glue there.) - 'if [ -d data/opt ]; then mkdir -p "${FLATPAK_DEST}/opt"; cp -a data/opt/. "${FLATPAK_DEST}/opt/"; fi' - 'if [ -d data/usr ]; then cp -a data/usr/. "${FLATPAK_DEST}/"; fi' - # O3DE fetches its own Python runtime on first use, writing into its install - # tree. That tree is read-only at runtime in a Flatpak, so bake Python in now - # while ${FLATPAK_DEST} is still writable. + # On first launch O3DE pip-installs its 'o3de' CLI editable ('pip install + # -e'), which writes an egg-info into read-only /app and fails. Force a + # normal install (built in a temp dir, lands in the writable ~/.o3de venv). - | set -e - ENGINE_DIR=$(find "${FLATPAK_DEST}/opt/O3DE" -mindepth 1 -maxdepth 1 -type d | head -n1) - echo "Engine dir: ${ENGINE_DIR}" - if [ -x "${ENGINE_DIR}/python/get_python.sh" ]; then - ( cd "${ENGINE_DIR}" && HOME="${PWD}" ./python/get_python.sh ) + LYPYTHON=$(find "${FLATPAK_DEST}/opt/O3DE" -path '*/cmake/LYPython.cmake' | head -n1) + if [ -n "$LYPYTHON" ] && grep -q 'set(_pip_install_mode_args "-e")' "$LYPYTHON"; then + sed -i 's/set(_pip_install_mode_args "-e")/set(_pip_install_mode_args "")/' "$LYPYTHON" else - echo "::warning:: get_python.sh not found; Python may fail at runtime" + echo "::warning:: editable-install line not found in LYPython.cmake" fi # Launcher + AppStream + desktop entry under the Flatpak app-id. - install -Dm755 o3de-wrapper.sh "${FLATPAK_DEST}/bin/o3de-wrapper.sh" - install -Dm644 org.o3de.O3DE.desktop "${FLATPAK_DEST}/share/applications/org.o3de.O3DE.desktop" - install -Dm644 org.o3de.O3DE.metainfo.xml "${FLATPAK_DEST}/share/metainfo/org.o3de.O3DE.metainfo.xml" - # NOTE: the .deb ships no clean application icon (only in-editor asset icons), - # so none is installed; the desktop entry falls back to a generic icon. Drop a - # real logo into the repo and install it here to fix the launcher icon. + - install -Dm644 org.o3de.O3DE.png "${FLATPAK_DEST}/share/icons/hicolor/256x256/apps/org.o3de.O3DE.png" sources: - type: file path: o3de.deb @@ -70,3 +62,5 @@ modules: path: org.o3de.O3DE.desktop - type: file path: org.o3de.O3DE.metainfo.xml + - type: file + path: org.o3de.O3DE.png diff --git a/scripts/make-flatpak.sh b/scripts/make-flatpak.sh index f467dfc3c..e0a6f19a4 100755 --- a/scripts/make-flatpak.sh +++ b/scripts/make-flatpak.sh @@ -29,21 +29,26 @@ tar -C data -xf data.tar.* mkdir -p "$DEST/opt" cp -a data/opt/. "$DEST/opt/" -echo ">> baking O3DE's Python runtime into the image" -# O3DE fetches Python into its install tree on first use, but that tree is -# read-only at runtime in a Flatpak, so populate it now while it is writable. -ENGINE_DIR=$(find "$DEST/opt/O3DE" -mindepth 1 -maxdepth 1 -type d | head -n1) -echo " engine dir: $ENGINE_DIR" -if [ -x "$ENGINE_DIR/python/get_python.sh" ]; then - ( cd "$ENGINE_DIR" && HOME="$PWD" ./python/get_python.sh ) +echo ">> patching the editable pip install (read-only /app workaround)" +# On first launch O3DE sets up a per-user Python venv in ~/.o3de and pip-installs +# its 'o3de' CLI with 'pip install -e' (editable). Editable mode writes an +# egg-info next to the source under /app, which is read-only in a Flatpak, so it +# fails. Force a normal (non-editable) install instead: pip builds in a temp dir +# and installs into the writable ~/.o3de venv. (Nothing Python-related needs to +# be baked into the image; it all lives per-user under ~/.o3de.) +LYPYTHON=$(find "$DEST/opt/O3DE" -path '*/cmake/LYPython.cmake' | head -n1) +if [ -n "$LYPYTHON" ] && grep -q 'set(_pip_install_mode_args "-e")' "$LYPYTHON"; then + sed -i 's/set(_pip_install_mode_args "-e")/set(_pip_install_mode_args "")/' "$LYPYTHON" + echo " patched: $LYPYTHON" else - echo " WARNING: get_python.sh not found; Python may fail at runtime" >&2 + echo " WARNING: editable-install line not found in LYPython.cmake; O3DE layout may have changed" >&2 fi echo ">> installing launcher + metadata" install -Dm755 o3de-wrapper.sh "$DEST/bin/o3de-wrapper.sh" install -Dm644 org.o3de.O3DE.desktop "$DEST/share/applications/$APP_ID.desktop" install -Dm644 org.o3de.O3DE.metainfo.xml "$DEST/share/metainfo/$APP_ID.metainfo.xml" +install -Dm644 org.o3de.O3DE.png "$DEST/share/icons/hicolor/256x256/apps/$APP_ID.png" echo ">> build-finish (command + sandbox permissions)" flatpak build-finish build-dir \