Packaging¶
packaging/
build/dist/ — Native AOT's idea of "self-contained" — is a directory,
not a file: GlavaSharp (the pwshim/x11shim Rust static libs are linked
in here), GlavaSharp.dbg (debug symbols, split out separately), and two
files Native AOT doesn't and can't statically link — libglfw.so.3.3 /
libglfw-wayland.so.3.3, OpenTK's GLFW native package, dynamically loaded
at startup — plus shaders/, deliberately shipped alongside rather than
embedded (see Shader Module Pipeline —
modules are loaded from disk by directory, not compiled in). None of that
is a bug; it just means "single self-contained executable" was only ever
true of the one GlavaSharp file itself, not the directory you actually
need to hand someone.
cmake --build build --target appimage (packaging/build-appimage.sh,
not part of the default ALL build since it needs network access on first
run) packs all of it into one real single-file .AppImage:
- Assembles
build/AppDir/frombuild/dist/verbatim (minusGlavaSharp.dbg— debug symbols aren't needed to run, and bloat the AppImage by more than the rest of it combined) underusr/bin/, pluspackaging/appimage/'sAppRun(a thin argv-passthrough script),GlavaSharp.desktop, andglavasharp.png— a static 2D reduction of theauroramodule's own look (layered wavy curtains colored by altitude, soft bloom, a starfield, atmospheric haze — see GlavaSharp-Original Modules for what it's echoing), generated bypackaging/appimage/generate-icon.py(numpy + Pillow, not a build dependency otherwise — rerun by hand and re-commit the PNG to retune it, it isn't regenerated as part ofcmake --build build --target appimage). - Fetches
appimagetoolfrom its GitHub releases on first run (cached underbuild/tools/afterwards) and runs it againstbuild/AppDir/. - Runs
appimagetoolitself withAPPIMAGE_EXTRACT_AND_RUN=1— it's shipped as an AppImage too, which would otherwise try to FUSE-mount itself, and not every machine running this build has/dev/fuseavailable (many CI containers don't). This only affects howappimagetoolruns during packaging; theGlavaSharpAppImage this produces supports both FUSE-mount and--appimage-extract-and-runfor whoever runs it later, same as any AppImage.
Why AppRun needs no logic beyond an argv passthrough: Program.cs
resolves the shader tree via AppContext.BaseDirectory (wherever the
running executable actually lives), and libglfw*.so resolution is
already relative to that same directory today (confirmed live — running
build/dist/GlavaSharp directly, with no LD_LIBRARY_PATH set, already
finds libglfw.so.3.3 sitting right next to it). Since
packaging/build-appimage.sh preserves that exact same relative layout
inside AppDir/usr/bin/, both keep resolving correctly once mounted —
verified live: GlavaSharp-x86_64.AppImage --module aurora, run from
/tmp (nowhere near the actual repo), logged shader paths resolving under
its own FUSE mount point (/tmp/.mount_.../usr/bin/shaders/...) and
compiled/linked normally.
The .desktop file exists because appimagetool requires (and validates)
one — Categories= values have to be real freedesktop.org registered
categories or prefixed X-; an early attempt using Visualization
unprefixed failed validation. Terminal=true since GlavaSharp is
fundamentally CLI-flag-driven (--desktop, --module, ...), not a
double-click GUI app with no arguments to pass.