Files
logos-plugin-qt/flake.nix
T
Dario Gabriel LipicarandClaude Opus 5 3d7e3e68b3 feat: the view templates exist once, and this repo is where
The four LogosView*.in templates had two byte-identical copies:

  logos-module-builder/cmake/                         (LIVE — LogosModule.cmake)
  logos-plugin-qt/tests/rep-file-plugin/cmake/        (fixture — rep-file-plugin)

Nothing compared them. This is the fifth defect of that exact shape in this
refactor, and it was created by the fix for the fourth: when this repo's
duplicate LogosModule.cmake was deleted, the templates it read were MOVED into
the fixture rather than removed, because the fixture still needed them.

It needed them because it cannot reach where they went. The edge runs
logos-module-builder -> logos-plugin-qt, one way, so a fixture inside this repo
can never consume logos-module-builder's copy, and this repo cannot re-export
it either. "Own them in the builder" is not reachable; a copy in the fixture is
what "own them in the builder" degrades into.

So ownership follows the direction that works. The templates are this repo's:

  * cmake/ holds the one copy, with cmake/README.md stating the rule and the
    argument for it.
  * packages.<sys>.logos-view-templates publishes them as a nameable output.
  * lib.buildPlugin / lib.generate set LOGOS_VIEW_TEMPLATE_DIR (cmake flag and
    env var) on every plugin build, so logos-module-builder's LogosModule.cmake
    receives the directory without either repo growing a new input.
  * devShellInputs exports it too, so a hand-run cmake in a module dev shell
    resolves it the same way.

LogosModule.cmake itself does NOT come back here. That file is the builder's
build-system contract and stays there; only the Qt-specific templates it
instantiates are published from this side of the edge.

The fixture now takes the directory from the harness and has nothing to fall
back to — a missing LOGOS_VIEW_TEMPLATE_DIR is a FATAL_ERROR, not a quiet
second copy. Proof it reads the owned file and not a leftover: changing the IID
in cmake/LogosViewReplicaFactory.h.in makes rep-file-plugin fail its
"IID found in binary" assertion.

rep-file-plugin is also added to CI. It is the check that instantiates these
templates and it was never listed in the workflow, so the templates had no CI
coverage at all — part of why a duplicate could sit in the fixture unnoticed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 09:07:05 -03:00

163 lines
6.6 KiB
Nix

{
description = "Logos Qt Plugin Backend — builds Logos modules as Qt 6 plugins, and the Qt host runtime they link";
inputs = {
logos-nix.url = "github:logos-co/logos-nix";
# Only needed for standalone dev/testing and the convenience lib wrapper.
# When used via logos-module-builder, logosModule is injected by the builder.
logos-module.url = "github:logos-co/logos-module";
nixpkgs.follows = "logos-nix/nixpkgs";
# The transport / consumer / token layer logos-qt-host is the Qt face of.
logos-protocol = {
url = "github:logos-co/logos-protocol";
inputs.logos-nix.follows = "logos-nix";
};
# The canonical LIDL frontend logos-qt-host-generator parses contracts with.
logos-lidl = {
url = "github:logos-co/logos-lidl";
inputs.logos-nix.follows = "logos-nix";
};
};
outputs = { self, nixpkgs, logos-module, logos-protocol, logos-lidl, ... }:
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; };
});
# Raw backend lib — no deps baked in.
# Callers (logos-module-builder) inject logosModule per call.
rawLib = import ./lib {
inherit nixpkgs;
inherit (nixpkgs) lib;
};
# Convenience wrapper that pre-fills logosModule from this flake's inputs.
# Used for standalone dev/testing.
wrappedLib = rawLib // {
buildPlugin = args: rawLib.buildPlugin (args // {
logosModule = logos-module.packages.${args.pkgs.system}.default;
});
buildHeaders = args: rawLib.buildHeaders args;
devShellInputs = pkgs: rawLib.devShellInputs pkgs {
logosModule = logos-module.packages.${pkgs.system}.default;
};
};
in {
# Default export: wrapped with logosModule pre-filled
lib = wrappedLib;
# Raw export: no deps — for use by logos-module-builder
rawLib = rawLib;
# The C++ half of this backend: the Qt host runtime a plugin links, and
# the generator that emits the plugin around a cdylib module's C ABI.
#
# These are deliberately NOT reachable from `lib` / `rawLib`. A consumer
# that only wants the Nix build functions (logos-module-builder's common
# path) must not be made to realise a Qt + protocol build to get them,
# and under Nix's laziness it is not — as long as nothing in those
# attributes mentions these.
#
# There is no `cmake-module` output any more. This repo used to ship its
# own cmake/LogosModule.cmake, and because logos-module-builder set
# LOGOS_MODULE_BUILDER_ROOT only when a MODULE carried that file (none
# does), every ui_qml plugin configured with THIS copy while every core
# module configured with the builder's. Both compiled; the divergence was
# invisible until something depended on it. The CMake module is the
# builder's build-system contract — it reads LOGOS_API_STYLE,
# LOGOS_MODULE_GO_STATIC_LIBS, generated_code/ — so it lives there, once.
#
# cmake/ came back for a narrower reason: the four LogosView*.in
# templates. Those had the mirror-image problem — they sat next to
# LogosModule.cmake in the builder, but this repo's rep-file-plugin
# fixture also instantiates them and cannot reach the builder, so it kept
# a byte-identical second copy with nothing comparing the two. See
# cmake/README.md.
packages = forAllSystems ({ pkgs, system, ... }: {
# The LogosView*.in templates, as a nameable output. `logos_module()`
# gets the same directory through LOGOS_VIEW_TEMPLATE_DIR; this output
# exists so a consumer (logos-module-builder's view-interface-abi
# check) can refer to the templates without depending on the layout of
# this repo's source tree.
logos-view-templates = pkgs.runCommand "logos-view-templates" { } ''
mkdir -p $out
cp ${./cmake}/LogosView*.in $out/
'';
logos-qt-host = import ./nix/qt-host.nix {
inherit pkgs;
src = ./.;
protocolLib = logos-protocol.packages.${system}.logos-protocol-lib;
};
logos-qt-host-generator = import ./nix/qt-host-generator.nix {
inherit pkgs;
src = ./qt-host-generator;
logos-lidl = logos-lidl.packages.${system}.logos-lidl;
};
# `default` was the CMake module (a cheap pure-Nix copy) until that
# output went away. The host runtime is what this repo now produces
# that a consumer can actually build, so `nix build` on it builds that.
default = self.packages.${pkgs.system}.logos-qt-host;
});
# Tests
checks = forAllSystems ({ pkgs, system, ... }: {
# Build a vanilla Qt plugin with no Logos SDK deps
vanilla-plugin = import ./tests/test-vanilla-plugin.nix {
inherit pkgs;
backendCommon = rawLib.common;
};
# Build a replica factory plugin from a .rep file
rep-file-plugin = import ./tests/test-rep-file-plugin.nix {
inherit pkgs;
backendCommon = rawLib.common;
};
# A failing logos-cpp-generator must fail the headers build; a module
# with no public API must not.
header-generator-guard = import ./tests/test-header-generator-guard.nix {
inherit pkgs;
};
# WHICH emitter buildHeaders picks, and whether it says so. A silent
# fall back to the legacy Qt emitter is green in every other check.
headers-emitter-routing = import ./tests/test-headers-emitter-routing.nix {
inherit pkgs;
inherit (rawLib) buildHeaders;
};
# The Qt host runtime compiles and installs a usable CMake package.
qt-host = self.packages.${system}.logos-qt-host;
# Drive the glue generator over a real contract and assert on the
# emitted C++.
qt-host-generator = import ./tests/test-qt-host-generator.nix {
inherit pkgs;
generator = self.packages.${system}.logos-qt-host-generator;
};
});
# Dev shell for working on the backend itself
devShells = forAllSystems ({ pkgs, ... }:
let
shell = wrappedLib.devShellInputs pkgs;
in {
default = pkgs.mkShell {
nativeBuildInputs = shell.nativeBuildInputs;
buildInputs = shell.buildInputs;
shellHook = ''
${shell.shellHook}
echo "Logos Qt Plugin Backend development environment"
'';
};
}
);
};
}