Repository navigation
build and run on Linux - #38
Merged
Merged
Conversation
The addon links libloot.so from loot_api on Linux and finds it through an $ORIGIN rpath; the worker and its parent talk over a unix socket in the temp directory instead of a named pipe, removed again on close. Paths cross the N-API boundary as std::string outside Windows, where libloot takes narrow strings. part of LAZ-1061
LOOT publishes no Linux binary, so the Linux job builds libloot's C++ wrapper from the release tag loot_api tracks, links the addon against it and runs the suite; the library it built is kept as a workflow artifact for vendoring. part of LAZ-1061
A js string arrives as utf-8 and a char8_t source decodes it as such on every platform, so the wide-string specialisations and the code page conversion behind them go. loadPlugins took wide strings unconditionally, which left the addon with an unresolved symbol on Linux. part of LAZ-1061
The socket gets a random uuid name in XDG_RUNTIME_DIR, which the desktop spec keeps private, falling back to the temp directory. Nothing is unlinked up front: a foreign file in a sticky temp directory fails that with EPERM, and closing the server removes the socket file. part of LAZ-1061
The rpath looks beside the addon first, where Vortex ships the library, then in loot_api for a checkout. The Linux job builds on the oldest hosted image so the library's glibc floor stays low, skips libloot's tests and caches the cargo build. part of LAZ-1061
part of LAZ-1061
Built by this repository's CI on ubuntu-22.04 from the release tag and stripped, as loot_api/readme.txt describes; the install-time node-gyp build links it on Linux the way it links libloot.lib on Windows. part of LAZ-1061
IDCs
marked this pull request as ready for review
September 22, 2026 13:20
One constrained template converts a js string to either std::string or std::filesystem::path, and the Windows error text reaches js through Napi::String instead of a code page conversion of our own, which was all that was left of string_cast. part of LAZ-1061
XDG_RUNTIME_DIR inherited from another user or a finished session is set but not writable; listening there would fail and leave LOOT dead for the session. part of LAZ-1061
The absolute module root is not quoted on the linker line, so a checkout path with a space broke the Linux link; the Windows block already links relatively. part of LAZ-1061
The "vendor libloot" workflow takes a release version, replaces the Windows binaries and headers in loot_api with the official release, builds and strips the Linux library from the same tag, bumps the package version and pushes a branch for a person to open the pull request from, since one the workflow token opened would start no CI run. CI builds the Linux library through the same composite action, at the version the vendored headers name, so the two cannot drift. Workflow tokens hold no more than the job needs. part of LAZ-1061
Aragas
approved these changes
Sep 22, 2026
This was referenced Sep 23, 2026
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 addon builds and runs on Linux, based on pikdum's port in #20 with the review findings applied on top.
Port (#20, kept under its author):
_WIN32guards, the worker connects to whatever endpoint path it is given,sortPluginsreturns a value on every path.Paths: every path crossing N-API is a
std::filesystem::pathbuilt fromchar8_t, which decodes the utf-8 the js side sends on both platforms; the wide-string specialisations and the code page conversion behind them are gone. Covered by new tests for a game installed under, and a masterlist read from, a directory namedSpiele ö 日本語 🎮, alongside the existing non-ascii plugin-name cases.IPC: the worker's socket gets a random uuid name in
XDG_RUNTIME_DIR, falling back to the temp directory; nothing is unlinked up front (a foreign file in a sticky temp dir would fail that withEPERM), and closing the server removes the socket file. Windows keeps its named pipe.Linking:
-L loot_api -l:libloot.so.0with rpath$ORIGIN:$ORIGIN/../../loot_api, so the library is found beside the addon where Vortex ships it, or inloot_apiin a checkout.Library: LOOT publishes no Linux binary, so CI builds libloot's C++ wrapper from the 0.29.6 tag on
ubuntu-22.04(glibc 2.34, GLIBCXX 3.4.29), strips it, runs the suite against it and keeps it as an artifact;loot_api/libloot.so.0is that artifact, provenance inloot_api/readme.txt. The cargo build is cached across runs.CI runs the full suite on both
windows-latestandubuntu-22.04(18/18 each). Verified live in a Vortex dev build on Windows against Skyrim SE with 675 plugins: three full plugin-info loads, a manual and a post-deployment sort, no IPC or archive errors.Not carried over from #20: the Nix flake for building libloot locally, since CI now does that build.
part of LAZ-1061