Repository navigation
Lay out the Linux release as a Unix prefix, and update flat installs to it - #350
Closed
startupfoundry wants to merge 3 commits into
Closed
startupfoundry wants to merge 3 commits into
startupfoundry wants to merge 3 commits into
Conversation
…to it
Packagers (an AUR package is planned) want the Linux download laid out as
a prefix they can copy to /usr. The release is now a tree,
halo-linux-i686-<config>.zip (the 32-bit x86 tree; halo-linux-x86_64 is another build):
bin/opence
lib/opence/libSDL3.so.0 (rpath $ORIGIN:$ORIGIN/../lib/opence, DT_RPATH kept)
share/opence/brokers.txt
share/applications/opence.desktop
share/icons/hicolor/<n>x<n>/apps/opence.png (16 to 512, tools/app_icon.py)
share/doc/opence/ (the READMEs)
share/licenses/opence/ (LICENSE.md and the carried licenses)
install_layout.c finds the game's files from its executable: bin/ beside
share/opence is a tree whose root is the game's folder; otherwise the
executable's folder is (build/linux/halo, the flat release). A portable
game keeps config.toml, maps/ and debug.txt in its folder, as before. An
installed one (a folder the player cannot write to, or a tree with
share/opence/packaged, which packages add) keeps them in
~/.config/halo-linux and ~/.local/share/halo-linux (the save root's
folder) and does not update itself. brokers.txt is the one beside
config.toml, else share/opence's. Windows, Android and the web are
unchanged.
Updates: the updaters already in players' hands take only a zip's
top-level files and ask for halo-linux-<config>.zip, so a tree under that
name would fail every update (checked: "the download is not a zip file
this build can read"). Releases therefore keep halo-linux-<config>.zip as
the same build laid out flat, which those updaters install as before. The
new updater asks for the tree's zip, unpacks folders (names checked: none
may leave the game's folder; links skipped; executables as the zip marks
them), and, run flat, moves the install to the tree: it puts a script that
starts bin/opence in place of halo, so Steam shortcuts keep working, and
deletes the flat files the tree moved. Replaced files are listed in
update-old.txt and deleted at the next start. debug.update_from
(HALO_UPDATE_FROM) updates from a local zip, for testing this without
GitHub.
The updater asks for halo-linux-i686-<config>.zip (UPDATE_PLATFORM
"linux-i686"); tools/test_linux_package.py checks that the updater,
ci_build.py and the workflow agree on both zips' names.
tools/linux_package.py lays out both (ci_build.py stages them; "tree" does
it for a source package) and zips them with their modes, which the
release job now uses, as GitHub's artifacts lose the executable bit.
Checked: the release built with tools/ci_build.py linux release; the tree
unpacked and started windowed; an install of origin/main's release updated
by origin/main's updater code (run against the local flat zip), then by
the new build to the tree, then started from bin/opence and from the halo
script, then updated tree to tree; the same old updater shown to fail on
the tree's zip alone; a read-only prefix and a writable one with
share/opence/packaged started with nothing written beside the executable,
the files in the XDG folders, and no update; tools/test_linux_package.py,
tools/test_install_layout.py, the new harness test of the updater's names
(with negative controls), tools/test_linux_port.py and tools/harness.
Not built here: Windows, Android and the web (their code paths compile to
what they were; updater.c was syntax-checked with _WIN32, HALO_ANDROID and
HALO_WEB).
…pdate an installed game A game whose folder cannot be written to counted as installed, and an installed game took config.toml from ~/.config/halo-linux and the game data from ~/.local/share/halo-linux only. So a portable copy on a read-only USB stick or mount, or an /opt/halo an administrator filled with maps, ignored the config.toml and maps/ beside the game, which the flat releases had read from there. A read-only folder without share/opence/packaged now keeps what it has: its config.toml and maps/ (matched without case, as the data root's is) are read in place, and only what it lacks goes to the XDG folders (those alone are made). A packaged tree still keeps everything in the XDG folders, as designed. Without a home folder (no XDG_CONFIG_HOME, XDG_DATA_HOME or HOME) the reason the game counted as installed was cleared, so install_is_system() returned 0 and the updater treated a packaged or /usr install as portable. The reason now stays: where the player's files go (the game's folder, whatever it allows) is decided apart from whether the game updates itself, and an installed game never does. Checked: tools/test_install_layout.py gains a read-only flat folder with config.toml and maps, a read-only folder with maps only, a read-only tree with and without maps, a packaged tree whose folder has config.toml and maps (still the XDG folders), a packaged tree and a read-only /usr tree with HOME unset (installed, files in the game's folder), and a portable tree with HOME unset; six of them fail on the previous install_layout.c.
The row of the network test's settings gave "off" as the default of them all, but debug.network_test_start is 15 seconds (port_config.c). The other debug.* rows were checked against port_config.c's entries (names, defaults, environment variables, platforms): every debug setting has a row in this README or the Android one, and none here is marked as for one processor only.
bnunu
requested review from
bnunu and
cybersecurity
and removed request for
cybersecurity
October 14, 2026 08:38
Collaborator
|
Conflicts in seven files, and its updater changes would have to be rewritten on top of the newer rollback and size checks. Please rebase it and then do a split resubmission. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Linux download becomes a prefix that packagers can copy into
/usras is, as ORION suggested on Discord with an AUR package in mind. The game also keeps working when it is just unpacked anywhere, and existing installs move over through the self-updater.Layout (
halo-linux-i686-<config>.zip):bin/opence: the executable takes the project's name instead of/usr/bin/halo. Steam's window class follows the executable name, so it matches the desktop entry. Developer builds are stillbuild/linux/halo.share/licenses/opence/, the Arch convention, rather than splitting them withshare/doc.Where the game finds its files (
port/linux/src/install_layout.c):bin/withshare/opence/beside it, the folder abovebin/is the game's folder. Otherwise, as today, it is the executable's own folder.config.toml,maps/anddebug.txtstay in that folder, as now.share/opence/packaged, which a package adds.~/.config/halo-linux/.~/.local/share/halo-linux/, the save root existing installs already use.-binpackage can repackage the release zip without rebuilding.Updates and migration.
halo-linux-<config>.zipand only take a zip's top-level files. Given a tree they fail ("the download is not a zip file this build can read"), so those players could never update again.halo-linux-<config>.zipfor now: the same build, laid out flat.halo-linux-i686-<config>.zipand moves the install to the tree. In place ofhaloit leaves a script that startsbin/opence, so Steam shortcuts keep working.update-old.txt).debug.update_from(HALO_UPDATE_FROM) updates from a local zip.Packaging.
tools/linux_package.pyis the one place the layout lives. It is used byci_build.pyand the release job; the release job now zips with it because GitHub's artifacts lose the executable bit.python tools/linux_package.py tree "$pkgdir/usr"lays out a source build.port/linux/README.mdcovers what goes where, thepackagedmarker and the runtime dependencies. A package can leave outlib/openceto use the system'slib32-sdl3.Test:
tools/test_linux_package.py, which also checks that the updater,ci_build.pyand the workflow agree on both zip names;tools/test_install_layout.py; and a harness test of the updater's name checks, with negative controls. They pass, as dotools/test_linux_port.pyandtools/harness(288).tools/ci_build.py linux releasebuilt both zips.bin/opence.mainrelease was updated bymain's own updater code through the new flat zip.bin/openceand from thehaloscript.main's updater was confirmed to fail on the tree zip alone./usr-style prefix and a writable prefix with thepackagedmarker both started with nothing written beside the executable and no update attempt.updater.cwas syntax-checked with_WIN32,HALO_ANDROIDandHALO_WEB. The workflow changes have not run on GitHub.