From d83526cbf0b76e2b71e60cbe7c479d0eaab417dd Mon Sep 17 00:00:00 2001 From: pc-heini Date: Tue, 16 Jun 2026 03:04:52 +0200 Subject: [PATCH] Bootstrap the per-user Python venv from the wrapper The Project Manager GUI does not set up O3DE's Python venv itself; it only errors ("Missing python venv file .../pyvenv.cfg") when it's absent, which cascades into "Failed to get engine info" / "Failed to initialize". Nothing was running get_python.sh on launch. The wrapper now runs python/get_python.sh when python.sh reports the venv is missing/stale. get_python.sh downloads Python, creates the venv under the writable ~/.o3de, and installs the o3de CLI from the prebuilt sdist. It is idempotent and self-heals a half-built venv (venv creation uses --clear). Co-Authored-By: Claude Opus 4.8 --- README.md | 11 +++++++---- o3de-wrapper.sh | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f7cdcd1e..50cec801 100644 --- a/README.md +++ b/README.md @@ -127,10 +127,13 @@ 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 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. +- **Python is per-user, not baked in.** O3DE needs a Python venv under `~/.o3de` + (writable), keyed to the engine path, so it can only be created at runtime — the + build can't bundle it. The Project Manager GUI does **not** create it itself, so + the wrapper (`o3de-wrapper.sh`) runs `python/get_python.sh` on launch when the + venv is missing or stale. The **first launch downloads Python and can take + several minutes with no window on screen** — that's expected; subsequent launches + are instant. (cmake, which `get_python.sh` needs, comes from the Sdk runtime.) - **The o3de CLI install (read-only `/app`).** On first launch O3DE installs its own `o3de` CLI from `scripts/o3de` into the per-user `~/.o3de` venv. By default `python/get_python.sh` does an *editable* install (`pip install -e`), which diff --git a/o3de-wrapper.sh b/o3de-wrapper.sh index a1f0bef5..b68fb23e 100755 --- a/o3de-wrapper.sh +++ b/o3de-wrapper.sh @@ -27,4 +27,24 @@ fi # Make libraries that sit next to the binary discoverable too. export LD_LIBRARY_PATH="$(dirname "$O3DE_BIN"):${LD_LIBRARY_PATH}" +# Bootstrap O3DE's per-user Python venv if needed. The Project Manager GUI does +# NOT set this up itself - it just errors out ("Missing python venv file ...") if +# the venv is absent. So we ensure it here. python.sh exits non-zero when the +# venv for this engine is missing/stale; get_python.sh then downloads Python, +# creates the venv (~/.o3de/Python, writable) and installs the 'o3de' CLI from +# the prebuilt sdist. It is idempotent and self-healing (recreates a broken venv +# with --clear). cmake, needed for the engine-id calc, ships in the Sdk runtime. +PYTHON_SH=$(find "$O3DE_ROOT" -type f -path '*/python/python.sh' 2>/dev/null | head -n 1) +GET_PYTHON=$(find "$O3DE_ROOT" -type f -path '*/python/get_python.sh' 2>/dev/null | head -n 1) +if [ -n "$GET_PYTHON" ]; then + if ! "$PYTHON_SH" --version >/dev/null 2>&1; then + echo "O3DE: setting up the per-user Python environment." >&2 + echo "O3DE: first launch downloads Python and can take several minutes..." >&2 + if ! "$GET_PYTHON"; then + echo "error: O3DE Python setup failed (see the log above)." >&2 + exit 1 + fi + fi +fi + exec "$O3DE_BIN" "$@"