mirror of
https://github.com/logos-co/logos-package-manager.git
synced 2026-08-27 10:11:07 +00:00
* 0.2.1
* feat(windows): cross-compile the CLI for x86_64-w64-mingw32
Exposes the x86_64-windows pseudo-system from `packages` only. The bundled
outputs stay Linux-only: nix-bundle-dir has no PE backend, and needs none
for a console tool -- PE import tables carry DLL base names rather than
paths (the format has no rpath), Windows searches the executable's own
directory first, and win-dll-link.sh already stages dependency DLLs there.
`checks` stays native too, since ctest cannot run PE binaries on the Linux
build host.
Four Windows-only defects, three of them silent:
* The C API header is explicitly __declspec(dllexport)-ed, and GNU ld
disables PE auto-export for the ENTIRE image as soon as any symbol is
explicitly exported -- so the un-annotated C++ classes the CLI uses
vanished from the export table (42 undefined references). Fixed with
-Wl,--export-all-symbols. NOTE: WINDOWS_EXPORT_ALL_SYMBOLS does NOT work
here; CMake emits no .def file at all under this cross toolchain and
reports nothing. Supplying CMAKE_OBJDUMP, the usual cause, made no
difference.
* installPhase looked only for .dylib/.so, so a correctly built DLL failed
with "No library file found". The liblgx copy beside it was worse: it
only WARNED, which on Windows would have shipped a package that links
and then cannot start.
* The runtime DLLs were installed to lib/. Windows resolves DLLs from the
executable's directory and win-dll-link.sh only scans $out/bin, so
lgpm.exe exited 53 with no output. They are now staged into bin/.
* The installed executable had no .exe suffix.
lgpm additionally used fs::path::native().rfind("..", 0) for its
install-path escape check. native() is std::wstring on Windows so that does
not compile, and the prefix test was imprecise anyway -- it also rejected a
legitimate directory named "..foo". Now compares the first path COMPONENT.
lgpd's applyCaBundle probed POSIX certificate paths only; on Windows every
probe misses and curl falls back to a compiled-in /nix/store path absent
from the target machine. Uses CURLSSLOPT_NATIVE_CA there instead.
* fix(windows): stage liblgx's transitive DLLs beside the library
Windows resolves a DLL from the EXECUTABLE's directory and PE has no rpath,
so every non-system DLL has to travel with the binary. Rather than maintain a
hand-written list, copy every *.dll from ${logosPackageLib}/bin -- that IS
liblgx's complete transitive closure, already computed there by nixpkgs'
win-dll-link.sh. Transitive by construction, so it cannot drift.
* feat: add --platform to install for another platform
lgpm computes the package variant from the machine it is running on, so
a cross-build could not use it: the Nix install bundler runs lgpm on the
Linux builder to lay out a Windows package, and it fail-closed with
Package does not contain variant for platform: linux-x86_64-dev
(package provides: windows-x86_64-dev)
That refusal is correct and worth keeping -- it is what stops a Windows
package being installed as a Linux one -- so the override is EXPLICIT
and never inferred from the environment. Without --platform, behaviour
is unchanged.
The override is applied at currentPlatformVariant(), so the alias and
-dev derivations in platformVariantsToTry() follow from it rather than
needing their own handling, and it is set before any command runs so
install, list and info agree on which platform is being managed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: never report an empty installed path for a package with no main file
A QML-only ui_qml package ships no backend library, so its manifest carries
"main": {}. installPluginFile() resolved *installedPluginPath from that map and
deliberately skipped the "<moduleName> + platform ext" fallback for ui_qml, so
the out-param stayed EMPTY on a completely successful install.
Every caller reads that emptiness as failure. package_manager_module gated its
uiPluginFileInstalled event on it (so Basecamp never rescanned and the plugin
only appeared after a restart) and put it in response["path"], which
logos-package-manager-ui reads as failure and renders as a red RETRY.
Resolution now lives in PackageManagerLib::resolveInstalledPackagePath(), which
returns the installed main FILE when the package ships one and the installed
module DIRECTORY otherwise. It is never empty on success. Consumers were
audited first: Basecamp's PackageCoordinator only logs the event payload and
then rescans, PMU ignores it, and UIPluginManager takes mainFilePath from the
SCAN (getInstalledUiPlugins) and already handles it being empty for a QML-only
plugin — nothing loads this path with QPluginLoader or takes its fileName().
Also in the same function:
- a manifest that declares a main file missing from the payload now warns on
stderr and reports the directory, instead of silently returning "";
- the platform chain tests _WIN32 first;
- the skipIfNotNewerVersion early return no longer hardcodes
isCoreModule=false — it reads "type" off the manifest it just parsed, so a
skipped CORE install stops being announced as a UI plugin.
Tests: tests/test_installed_path.cpp drives the manifest-shape matrix through
resolveInstalledPackagePath (the "main": {} shape cannot be built through
liblgx's C API — lgx_add_variant only permits a main-less directory variant for
a manifest that already declares type ui_qml, and there is no lgx_set_type())
plus end-to-end installPluginFile cases. test_uninstall.cpp gains the symmetric
QML-only case, which already worked: uninstall keys off installDir and type,
never off "main".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(windows): a read-only payload file aborted the install after it succeeded
Windows refuses to DELETE a file carrying FILE_ATTRIBUTE_READONLY; POSIX
consults only the parent directory's write bit. Everything in the Nix store is
0444 and nix-bundle-lgx copied a module's `icon:` straight out of it, so every
.lgx with an icon shipped exactly one read-only file. Measured on the extracted
payload: the root hello.svg was "ReadOnly, Archive" while both DLLs, the
manifests, qmldir, Main.qml, variant and even icons/hello.svg were "Archive".
installPluginFile writes every payload file and then calls
fs::remove_all(tempDir) -- the THROWING overload. The resulting
filesystem_error was uncaught: in the lgpm CLI it reached terminate(), and
inside the package_manager module it unwound out of the call so the install
reply was never sent. The files were all on disk and the package manager showed
a red "Retry". Reproduced outside Basecamp:
terminate called after throwing an instance of 'std::filesystem::filesystem_error'
what(): cannot remove all: Access is denied
[...\Temp\lgpm_extract_cfeb4abebd820901\windows-x86_64\hello.svg]
The same trap made every uninstall and upgrade fail on Windows with "Failed to
remove install directory: Access is denied", because the INSTALLED icon carries
the attribute too.
Temp cleanup now goes through removeTreeQuietly: non-throwing, retried once
with the read-only bits cleared, and a warning rather than a failure if it
still will not go -- an undeletable temp directory is untidy, never a reason to
fail an install that has already succeeded. The install-directory removal
clears the attributes and retries before reporting, where the failure IS
load-bearing.
Uses fs::permissions rather than <windows.h>, whose `interface` macro and
TokenSource enumerator have twice broken unrelated files in this tree.
Verified on real Windows: the FIXED lgpm installs the SAME already-published
package that crashed the shipped one -- exit 0, all files present, temp
directory cleaned. That backwards compatibility matters, because packages
carrying the read-only icon are already published.
* chore(deps): re-pin logos-nix and nix-bundle-dir to their merged revs
L1 (logos-nix) and L2 (nix-bundle-dir) are on their default branches now, so
the lock can name the merged revs instead of the pre-merge branch tips it was
resolving against while those PRs were open.
logos-package needs no change here. This commit originally repinned it too, but
the rebase onto master picked up #29, which already moved it to the rev master's
new manifestVersion code needs. Taking master's lock as the base and re-running
the update, rather than hand-merging the conflict, is what keeps that pin
intact.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
332 lines
8.7 KiB
JSON
332 lines
8.7 KiB
JSON
{
|
|
"nodes": {
|
|
"logos-nix": {
|
|
"inputs": {
|
|
"nixpkgs": "nixpkgs",
|
|
"nixpkgs-windows": "nixpkgs-windows"
|
|
},
|
|
"locked": {
|
|
"lastModified": 1786399295,
|
|
"narHash": "sha256-Bl1A0UgsIXioZw5uEW8Jl5u7FfZcFMnpYlpsdezFwK0=",
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"rev": "6e0f4a7120fced10829b0b3a698ff619a11d4605",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"logos-nix_2": {
|
|
"inputs": {
|
|
"nixpkgs": "nixpkgs_2",
|
|
"nixpkgs-windows": "nixpkgs-windows_2"
|
|
},
|
|
"locked": {
|
|
"lastModified": 1786399295,
|
|
"narHash": "sha256-Bl1A0UgsIXioZw5uEW8Jl5u7FfZcFMnpYlpsdezFwK0=",
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"rev": "6e0f4a7120fced10829b0b3a698ff619a11d4605",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"logos-nix_3": {
|
|
"inputs": {
|
|
"nixpkgs": "nixpkgs_3"
|
|
},
|
|
"locked": {
|
|
"lastModified": 1773955630,
|
|
"narHash": "sha256-KqzMoWYIVp2xMgphs7v02T/BE54RKMFxpdC2duhJKG0=",
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"rev": "0e9e6d66ab8eb34f59e45ed448f7dc29130feb88",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"logos-nix_4": {
|
|
"inputs": {
|
|
"nixpkgs": "nixpkgs_4"
|
|
},
|
|
"locked": {
|
|
"lastModified": 1773955630,
|
|
"narHash": "sha256-KqzMoWYIVp2xMgphs7v02T/BE54RKMFxpdC2duhJKG0=",
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"rev": "0e9e6d66ab8eb34f59e45ed448f7dc29130feb88",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"logos-nix_5": {
|
|
"inputs": {
|
|
"nixpkgs": "nixpkgs_5",
|
|
"nixpkgs-windows": "nixpkgs-windows_3"
|
|
},
|
|
"locked": {
|
|
"lastModified": 1786399295,
|
|
"narHash": "sha256-Bl1A0UgsIXioZw5uEW8Jl5u7FfZcFMnpYlpsdezFwK0=",
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"rev": "6e0f4a7120fced10829b0b3a698ff619a11d4605",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "logos-nix",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"logos-package": {
|
|
"inputs": {
|
|
"logos-nix": "logos-nix_2",
|
|
"nixpkgs": [
|
|
"logos-package",
|
|
"logos-nix",
|
|
"nixpkgs"
|
|
]
|
|
},
|
|
"locked": {
|
|
"lastModified": 1786463662,
|
|
"narHash": "sha256-h2ex453W73qjkN8n6Bo9ywU5X22bssmyCMpQjR5LRzY=",
|
|
"owner": "logos-co",
|
|
"repo": "logos-package",
|
|
"rev": "3cb520c8eadde3d6d7810dee74bdd243f73f34e9",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "logos-package",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nix-bundle-appimage": {
|
|
"inputs": {
|
|
"logos-nix": "logos-nix_3",
|
|
"nix-bundle-dir": "nix-bundle-dir",
|
|
"nixpkgs": [
|
|
"nix-bundle-appimage",
|
|
"logos-nix",
|
|
"nixpkgs"
|
|
]
|
|
},
|
|
"locked": {
|
|
"lastModified": 1774455478,
|
|
"narHash": "sha256-S8IMfdDc+2Wwri0krLDsIUwSqmwanmvHAJWHOFo8ykk=",
|
|
"owner": "logos-co",
|
|
"repo": "nix-bundle-appimage",
|
|
"rev": "2428125a4a1b34ad9119efa97edb98676283e3da",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "nix-bundle-appimage",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nix-bundle-dir": {
|
|
"inputs": {
|
|
"logos-nix": "logos-nix_4",
|
|
"nixpkgs": [
|
|
"nix-bundle-appimage",
|
|
"nixpkgs"
|
|
]
|
|
},
|
|
"locked": {
|
|
"lastModified": 1773961179,
|
|
"narHash": "sha256-bpaTvz//R8WFP5xnnDLv3a9l7unDmBwJjCewx3wCjzM=",
|
|
"owner": "logos-co",
|
|
"repo": "nix-bundle-dir",
|
|
"rev": "cd214dbf15487d80967389847ae2210468be6ebf",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "nix-bundle-dir",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nix-bundle-dir_2": {
|
|
"inputs": {
|
|
"logos-nix": "logos-nix_5",
|
|
"nixpkgs": [
|
|
"nix-bundle-dir",
|
|
"logos-nix",
|
|
"nixpkgs"
|
|
]
|
|
},
|
|
"locked": {
|
|
"lastModified": 1786415152,
|
|
"narHash": "sha256-0JUD+57+VTO25IfJjy92av5T88pmMSod8wMygW9OK3s=",
|
|
"owner": "logos-co",
|
|
"repo": "nix-bundle-dir",
|
|
"rev": "f843b8ec76974881ccf8619157ae63bfa2017a5e",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "logos-co",
|
|
"repo": "nix-bundle-dir",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nixpkgs": {
|
|
"locked": {
|
|
"lastModified": 1759036355,
|
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "NixOS",
|
|
"ref": "nixos-unstable",
|
|
"repo": "nixpkgs",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nixpkgs-windows": {
|
|
"locked": {
|
|
"lastModified": 1782723713,
|
|
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nixpkgs-windows_2": {
|
|
"locked": {
|
|
"lastModified": 1782723713,
|
|
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nixpkgs-windows_3": {
|
|
"locked": {
|
|
"lastModified": 1782723713,
|
|
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nixpkgs_2": {
|
|
"locked": {
|
|
"lastModified": 1759036355,
|
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "NixOS",
|
|
"ref": "nixos-unstable",
|
|
"repo": "nixpkgs",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nixpkgs_3": {
|
|
"locked": {
|
|
"lastModified": 1759036355,
|
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "NixOS",
|
|
"ref": "nixos-unstable",
|
|
"repo": "nixpkgs",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nixpkgs_4": {
|
|
"locked": {
|
|
"lastModified": 1759036355,
|
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "NixOS",
|
|
"ref": "nixos-unstable",
|
|
"repo": "nixpkgs",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"nixpkgs_5": {
|
|
"locked": {
|
|
"lastModified": 1759036355,
|
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
|
"owner": "NixOS",
|
|
"repo": "nixpkgs",
|
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
|
"type": "github"
|
|
},
|
|
"original": {
|
|
"owner": "NixOS",
|
|
"ref": "nixos-unstable",
|
|
"repo": "nixpkgs",
|
|
"type": "github"
|
|
}
|
|
},
|
|
"root": {
|
|
"inputs": {
|
|
"logos-nix": "logos-nix",
|
|
"logos-package": "logos-package",
|
|
"nix-bundle-appimage": "nix-bundle-appimage",
|
|
"nix-bundle-dir": "nix-bundle-dir_2",
|
|
"nixpkgs": [
|
|
"logos-nix",
|
|
"nixpkgs"
|
|
]
|
|
}
|
|
}
|
|
},
|
|
"root": "root",
|
|
"version": 7
|
|
}
|