Files
logos-liblogos/flake.nix
T
Dario Gabriel LipicarandClaude Opus 5 6be8eb0c01 chore(deps): move onto logos-protocol 0.8 and logos-plugin-qt master
logos-plugin-qt#26 makes protocol 0.8 a HARD FLOOR for every consumer of
logos-qt-host: cpp/logos_provider_object.cpp and cpp/qt_provider_object.cpp call
TokenManager::saveInboundToken unguarded, so the two inputs move together or not
at all. liblogos links logos-qt-host directly, and it is upstream of both apps
(each nix/app.nix copies liblogos's lib/* over the app), so it goes first.

  logos-protocol   2e3344ac -> 42460e5b  (0.7 -> 0.8, protocol#73)
  logos-plugin-qt  1aa3e31c -> 048152f2  (plugin-qt#26)

NO CODE CHANGES, and that was checked rather than assumed. 0.8 changes which
store ModuleProxy::authorize reads, so every token site here was classified:

  module_manager.cpp:336  saveToken(name, authToken)   OUTBOUND, still correct
  module_manager.cpp:132  getToken("capability_module") outbound read
  module_manager.cpp:219  getToken("capability_module") outbound read
  logos_core.cpp:82       getToken(key)                 outbound read
  module_manager.cpp:223  client->informModuleToken(...) inbound grant, over the
                          wire -- 0.8 routes it through saveInboundToken on the
                          RECEIVING side, which is a different process here

:336 is the host caching a module's OWN host-issued credential under that
module's name; protocol pins that meaning in
TokenDirection.TheOwnCredentialStillAuthorizesAndStillGatesPushes. liblogos is
therefore NOT an instance of the "seeded a peer's token through the outbound
door, then expected to authorize an inbound call against it" defect -- it
authorizes no inbound call at all: it registers no provider anywhere in src/,
and its default loader puts every target in another process.

Verified by BUILDING all ten outputs individually with --print-out-paths, on a
24-core x86_64-linux box:

  x86_64-linux    lib bin include modules tests default portable  all OK
  checks.tests    185 tests, 0 failures, 0 errors
  x86_64-windows  default portable                                all OK

Closure audit (nix-store -qR on packages.<sys>.default), which is the thing this
whole layer exists to keep at one:

  x86_64-linux    1 logos-qt-host (ka5vgzb8…)
                  1 logos-protocol derivation at 0.8, 3 outputs
                    (…-lib-0.8.0, …-headers-0.8.0, and the symlinkJoin)
  x86_64-windows  1 logos-qt-host (cksg9kw6…-x86_64-w64-mingw32)
                  1 logos-protocol-lib-x86_64-w64-mingw32-0.8.0

liblogos-bin's lib/liblogos_qt_host.so is a re-export COPY of the input's and
compares byte-identical to it, so the two paths are one image. logos-qt-sdk no
longer ships a qt-host of its own; it only propagates that one.

Not fixed here, and now documented at the logos-capability-module input with the
measurement: the capability_module this repo SHIPS is built by its own
logos-module-builder chain against logos-protocol 0.4.0 and a pre-#26
logos-qt-host, so the repo really does emit two logos-qt-host images -- invisible
to nix-store -qR because the plugin's references are scrubbed. The five-line
`follows` that closes it was written and measured (lock 211 -> 174, symbols
58 -> 71, Linux fully green) and then REJECTED: it makes capability_module the
first module on plugin-qt master's >=0.8 glue, which emits a direct call to
logos_module_accept_inbound_token that no backend defines yet -- neither
logos-cpp-sdk's pinned rev nor its master. On ELF that links cleanly with an
undefined symbol; the Windows cross-build is what turns it into an error. Add
those follows in the same wave as the logos-cpp-sdk emitter, not before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 10:41:44 -03:00

217 lines
11 KiB
Nix

{
description = "Logos liblogos core library";
inputs = {
logos-nix.url = "github:logos-co/logos-nix";
nixpkgs.follows = "logos-nix/nixpkgs";
logos-cpp-sdk.url = "github:logos-co/logos-cpp-sdk";
logos-cpp-sdk.inputs.logos-protocol.follows = "logos-protocol";
logos-protocol.url = "github:logos-co/logos-protocol";
logos-qt-sdk.url = "github:logos-co/logos-qt-sdk";
logos-plugin-qt.url = "github:logos-co/logos-plugin-qt";
logos-capability-module.url = "github:logos-co/logos-capability-module";
logos-module.url = "github:logos-co/logos-module";
process-stats.url = "github:logos-co/process-stats";
logos-container.url = "github:logos-co/logos-container";
logos-module-loader.url = "github:logos-co/logos-module-loader";
default-container.url = "github:logos-co/logos-container-subprocess";
default-module-loader.url = "github:logos-co/logos-module-loader-qt";
logos-package-manager.url = "github:logos-co/logos-package-manager";
};
outputs = { self, nixpkgs, logos-nix, logos-cpp-sdk, logos-protocol, logos-qt-sdk, logos-plugin-qt, logos-capability-module, logos-module, logos-package-manager, process-stats, logos-container, default-container, logos-module-loader, default-module-loader }:
let
systems = [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f {
inherit system;
pkgs = import nixpkgs { inherit system; };
logosSdk = logos-cpp-sdk.packages.${system}.default;
logosProtocolPkg = logos-protocol.packages.${system}.default;
logosQtSdk = logos-qt-sdk.packages.${system}.default;
logosQtHost = logos-plugin-qt.packages.${system}.logos-qt-host;
capabilityModule = logos-capability-module.packages.${system}.default;
logosModule = logos-module.packages.${system}.default;
processStats = process-stats.packages.${system}.default;
logosContainer = logos-container.packages.${system}.default;
logosModuleLoader = logos-module-loader.packages.${system}.default;
defaultContainer = default-container.packages.${system}.default;
defaultModuleLoader = default-module-loader.packages.${system}.default;
logosPackageManager = logos-package-manager.packages.${system}.lib;
logosPackageManagerPortable = logos-package-manager.packages.${system}.lib-portable;
});
# Same as forAllSystems, plus the "x86_64-windows" pseudo-system. This
# cannot just be logos-nix.lib.forAllTargets, because that only supplies
# { system, pkgs } and this flake threads a dozen per-system dependencies
# through.
#
# Every dependency below is a TARGET-side artifact (headers, archives, or
# DLLs linked into logos_core, plus the host binary / plugin that are
# merely re-exported). liblogos runs NO code generator at build time
# (verified: no logos-cpp-generator / qt-generator anywhere in this repo),
# so nothing here needs to come from the build platform's package set.
#
# Applied to `packages` ONLY: `checks` would have to execute PE test
# binaries on the Linux builder, and a cross devShell offers no way to run
# what it produces.
windowsBuildSystem = "x86_64-linux";
forAllTargets = f:
nixpkgs.lib.genAttrs (systems ++ [ "x86_64-windows" ]) (system: f {
inherit system;
pkgs =
if system == "x86_64-windows"
then logos-nix.lib.mkWindowsPkgs { buildSystem = windowsBuildSystem; }
else import nixpkgs { inherit system; };
logosSdk = logos-cpp-sdk.packages.${system}.default;
logosProtocolPkg = logos-protocol.packages.${system}.default;
logosQtSdk = logos-qt-sdk.packages.${system}.default;
logosQtHost = logos-plugin-qt.packages.${system}.logos-qt-host;
capabilityModule = logos-capability-module.packages.${system}.default;
logosModule = logos-module.packages.${system}.default;
processStats = process-stats.packages.${system}.default;
logosContainer = logos-container.packages.${system}.default;
logosModuleLoader = logos-module-loader.packages.${system}.default;
defaultContainer = default-container.packages.${system}.default;
defaultModuleLoader = default-module-loader.packages.${system}.default;
logosPackageManager = logos-package-manager.packages.${system}.lib;
logosPackageManagerPortable = logos-package-manager.packages.${system}.lib-portable;
});
in
{
packages = forAllTargets ({ pkgs, system, logosSdk, logosProtocolPkg, logosQtSdk, logosQtHost, capabilityModule, logosModule, processStats, logosContainer, logosModuleLoader, defaultContainer, defaultModuleLoader, logosPackageManager, logosPackageManagerPortable }:
let
# The built-in default container + format-loader implementations — the
# single place the default is chosen. Each is just the package; it
# ships a generic CMake config (LogosContainerImpl / LogosFormatLoaderImpl)
# that carries its library and deps, which liblogos find_package's. Swap
# an entry to change the default — no C++, CMake, or nix-flag change.
containerImpl = defaultContainer;
formatLoaderImpl = defaultModuleLoader;
# Common configuration (dev, default)
common = import ./nix/default.nix {
inherit pkgs logosSdk logosProtocolPkg logosQtSdk logosQtHost logosModule processStats logosContainer logosModuleLoader logosPackageManager containerImpl formatLoaderImpl;
};
# Common configuration (portable)
commonPortable = import ./nix/default.nix {
inherit pkgs logosSdk logosProtocolPkg logosQtSdk logosQtHost logosModule processStats logosContainer logosModuleLoader containerImpl formatLoaderImpl;
logosPackageManager = logosPackageManagerPortable;
portableBuild = true;
};
src = ./.;
# Shared build that compiles everything (dev)
build = import ./nix/build.nix { inherit pkgs common src; };
# Shared build (portable)
buildPortable = import ./nix/build.nix { inherit pkgs src; common = commonPortable; };
# Individual package components (reference the shared build)
lib = import ./nix/lib.nix { inherit pkgs common build; };
modules = import ./nix/modules.nix { inherit pkgs common capabilityModule; };
modulesPortable = import ./nix/modules.nix { inherit pkgs capabilityModule; common = commonPortable; portableBuild = true; };
bin = import ./nix/bin.nix { inherit pkgs common build lib modules formatLoaderImpl; };
include = import ./nix/include.nix { inherit pkgs common src logosSdk; inherit logosProtocolPkg logosQtSdk logosQtHost; };
tests = import ./nix/tests.nix { inherit pkgs common build; };
# Portable package components
libPortable = import ./nix/lib.nix { inherit pkgs; common = commonPortable; build = buildPortable; };
binPortable = import ./nix/bin.nix { inherit pkgs formatLoaderImpl; common = commonPortable; build = buildPortable; lib = libPortable; modules = modulesPortable; };
includePortable = import ./nix/include.nix { inherit pkgs src logosSdk; inherit logosProtocolPkg logosQtSdk logosQtHost; common = commonPortable; };
# Combined package (dev)
#
# propagatedBuildInputs is set HERE as well as on the headers output,
# and that is not redundant: symlinkJoin builds a NEW derivation and
# does not carry the propagation of the paths it joins. Consumers take
# this join, not the headers output, so setting it only there reaches
# nobody -- measured, logos-module-viewer still failed with
# fatal error: nlohmann/json.hpp: No such file or directory
# until it was set on the join too.
#
# nlohmann is needed because this output re-exports the Qt host runtime
# headers, two of which (logos_provider_object.h, logos_qt_arg_decode.h)
# include <nlohmann/json.hpp>. Consumers going through
# find_package(logos-qt-host) get it transitively; consumers taking the
# include directory directly do not.
liblogos = pkgs.symlinkJoin {
name = "logos-liblogos";
paths = [ bin lib include ];
propagatedBuildInputs = [ pkgs.nlohmann_json ];
};
# Combined package (portable)
liblogosPortable = pkgs.symlinkJoin {
name = "logos-liblogos-portable";
paths = [ binPortable libPortable includePortable ];
propagatedBuildInputs = [ pkgs.nlohmann_json ];
};
in
{
# Individual outputs
logos-liblogos-bin = bin;
logos-liblogos-lib = lib;
logos-liblogos-include = include;
logos-liblogos-modules = modules;
# Combined output
logos-liblogos = liblogos;
# Portable output (compiled with LOGOS_PORTABLE_BUILD)
portable = liblogosPortable;
# Default package (dev)
default = liblogos;
}
# The test suite is POSIX-only (posix_spawn/waitpid/kill, /bin/sh) and
# CMake gates it off for a Windows host, so `ninja logos_core_tests`
# would have no such target. Not exposing the output at all beats
# shipping one that cannot be built.
// pkgs.lib.optionalAttrs (!pkgs.stdenv.hostPlatform.isWindows) {
logos-liblogos-tests = tests;
}
);
checks = forAllSystems ({ pkgs, system, ... }:
let
testsPkg = self.packages.${system}.logos-liblogos-tests;
# Real Qt plugin used by RealPluginRegistryTest (TEST_PLUGIN env var).
# capability_module is already a flake input and builds a real plugin.
capabilityModulePkg = logos-capability-module.packages.${system}.default;
pluginExt = if pkgs.stdenv.isDarwin then "dylib" else "so";
in {
tests = pkgs.runCommand "logos-liblogos-tests" {
nativeBuildInputs = [ testsPkg ] ++ pkgs.lib.optionals pkgs.stdenv.isLinux [ pkgs.qt6.qtbase ];
} ''
export QT_QPA_PLATFORM=offscreen
${pkgs.lib.optionalString pkgs.stdenv.isLinux ''
export QT_PLUGIN_PATH="${pkgs.qt6.qtbase}/${pkgs.qt6.qtbase.qtPluginPrefix}"
''}
export TEST_PLUGIN="${capabilityModulePkg}/lib/capability_module_plugin.${pluginExt}"
mkdir -p $out
echo "Running logos-liblogos tests..."
echo "TEST_PLUGIN=$TEST_PLUGIN"
${testsPkg}/bin/logos_core_tests --gtest_output=xml:$out/test-results.xml
'';
}
);
devShells = forAllSystems ({ pkgs, ... }: {
default = pkgs.mkShell {
nativeBuildInputs = [
pkgs.cmake
pkgs.ninja
pkgs.pkg-config
];
buildInputs = [
pkgs.qt6.qtbase
pkgs.qt6.qtremoteobjects
pkgs.zstd
pkgs.spdlog
];
};
});
};
}