mirror of
https://github.com/logos-co/logos-basecamp.git
synced 2026-08-27 14:51:07 +00:00
fix(windows): app.nix copied no shared libraries at all
The liblogos shared-library loop globbed *.dylib and *.so only. On Windows it matched nothing, and because each candidate is guarded by `[ -f "$f" ]` with a trailing `|| true`, it copied zero files and exited 0. Thirteen DLLs sit in that same lib/ -- liblogos_core, libpackage_manager_lib, liblgx, icuuc76, icudt76, libsodium-26 and the mingw runtime -- and LogosBasecamp.exe imports liblogos_core.dll DIRECTLY. The result is 0xC0000135 (STATUS_DLL_NOT_FOUND) before main(): no Qt error, no stderr, no output whatsoever. It has only ever run on Windows because those DLLs were hand-staged into the payload. Adds *.dll to the glob, sends DLLs to bin/ rather than lib/ (Windows searches the executable's own directory, has no rpath, and win-dll-link.sh only processes $out/bin), and makes copying zero libraries a hard error -- this loop exiting 0 having done nothing is the whole defect. Also corrects the comment on bundleFor. It claimed skipping nix-bundle-dir on Windows was right because a PE needs no relocation. That conflates the bundler's two jobs: relocation (genuinely unnecessary on PE) and Qt plugin / QML / qt.conf staging (required on every platform, since those DLLs are LoadLibrary'd and appear in no import table). Skipping it yields a bundle with no qt.conf and no QPA plugin. The comment now says so and names the real fix.
This commit is contained in:
@@ -265,15 +265,28 @@
|
||||
mainProgram = "LogosBasecamp";
|
||||
};
|
||||
});
|
||||
# nix-bundle-dir is the ELF/Mach-O relocator: it rewrites rpaths and
|
||||
# install names so the binaries stop pointing into /nix/store. A PE
|
||||
# has neither -- its import table carries DLL BASE NAMES only, and
|
||||
# Windows searches the executable's own directory first -- so the
|
||||
# Windows build is ALREADY relocatable and nixpkgs' win-dll-link.sh
|
||||
# has staged the closure into bin/. Running bundle.sh over it would
|
||||
# not help; it branches `file -b` on Mach-O|ELF with no PE case and
|
||||
# would emit an EMPTY payload while exiting 0. nix-bundle-lgx skips
|
||||
# it on Windows for exactly this reason (d539a3f); do the same here.
|
||||
# INTERIM, and neither branch of this is right yet -- see below.
|
||||
#
|
||||
# nix-bundle-dir does two separable jobs. (a) RELOCATION: rewriting
|
||||
# rpaths / install names so binaries stop pointing into /nix/store.
|
||||
# A PE genuinely needs none of that -- its import table carries DLL
|
||||
# BASE NAMES only, Windows searches the executable's own directory
|
||||
# first, and win-dll-link.sh has already staged bin/. (b) Qt STAGING:
|
||||
# the Qt plugin scan, the QML module scan and qt.conf generation.
|
||||
# (b) is FORMAT-AGNOSTIC and is required on Windows just as much as
|
||||
# anywhere else -- Qt plugins and QML module DLLs are LoadLibrary'd,
|
||||
# so nothing in the import closure reveals them.
|
||||
#
|
||||
# Running the bundler unmodified on Windows takes the (a) path, whose
|
||||
# `file -b` chain has no PE case, and emits an EMPTY payload while
|
||||
# exiting 0. Skipping it entirely -- what this does -- keeps the app
|
||||
# and the modules but produces no qt.conf, no lib/qt-6/plugins and no
|
||||
# qwindows.dll, so the app cannot start either.
|
||||
#
|
||||
# The real fix is a PE branch in nix-bundle-dir's bundle.sh that skips
|
||||
# (a) and keeps (b), plus a fixpoint sweep of the DLL closure over the
|
||||
# staged plugins. When that lands, DELETE bundleFor and go back to
|
||||
# dirBundler on every platform.
|
||||
winBundler = drv: drv;
|
||||
bundleFor = if onWindows then winBundler else dirBundler;
|
||||
binBundleDir = withMainProgram (bundleFor appDistributed);
|
||||
|
||||
+30
-3
@@ -332,12 +332,39 @@ WRAPPER_EOF
|
||||
fi
|
||||
done
|
||||
|
||||
# Copy shared libraries from liblogos (includes logos_core and its dependency package_manager_lib)
|
||||
for f in "${logosLiblogos}/lib/"*.dylib "${logosLiblogos}/lib/"*.so; do
|
||||
# Copy shared libraries from liblogos (includes logos_core and its dependency
|
||||
# package_manager_lib).
|
||||
#
|
||||
# The glob listed only *.dylib and *.so, so on Windows it matched NOTHING and
|
||||
# -- guarded by `[ -f ]` and `|| true` -- copied nothing while exiting 0. The
|
||||
# thirteen DLLs sitting in that same lib/ (liblogos_core, libpackage_manager_lib,
|
||||
# liblgx, icuuc76, icudt76, libsodium-26, ...) were silently dropped, and
|
||||
# LogosBasecamp.exe imports liblogos_core.dll DIRECTLY: the app died at
|
||||
# 0xC0000135 (STATUS_DLL_NOT_FOUND) before main(), which produces no Qt error,
|
||||
# no stderr, no output of any kind. It only ever ran because those DLLs were
|
||||
# hand-staged into the payload by the operator.
|
||||
#
|
||||
# DLLs go to bin/, NOT lib/. Windows searches the executable's own directory
|
||||
# first and has no rpath, and nixpkgs' win-dll-link.sh (which pulls in the rest
|
||||
# of the closure) only ever processes $out/bin.
|
||||
_libdest="$out/lib"
|
||||
${pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isWindows ''_libdest="$out/bin"''}
|
||||
_copied=0
|
||||
for f in "${logosLiblogos}/lib/"*.dylib "${logosLiblogos}/lib/"*.so "${logosLiblogos}/lib/"*.dll; do
|
||||
# A non-matching glob stays literal, so test before copying.
|
||||
if [ -f "$f" ]; then
|
||||
cp -L "$f" "$out/lib/" || true
|
||||
cp -L "$f" "$_libdest/" || true
|
||||
_copied=$((_copied + 1))
|
||||
fi
|
||||
done
|
||||
echo "Installed $_copied shared librar(y|ies) from liblogos into $_libdest"
|
||||
# Assert rather than trust: this loop silently copying zero is exactly the
|
||||
# defect above, and it exits 0 either way.
|
||||
if [ "$_copied" -eq 0 ]; then
|
||||
echo "ERROR: copied no shared libraries from ${logosLiblogos}/lib" >&2
|
||||
ls -la "${logosLiblogos}/lib" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy SDK library if it exists
|
||||
if ls "${logosSdk}/lib/"liblogos_sdk.* >/dev/null 2>&1; then
|
||||
|
||||
Reference in New Issue
Block a user