mirror of
https://github.com/logos-co/logos-plugin-qt.git
synced 2026-08-27 08:51:07 +00:00
Merge pull request #5 from logos-co/move_non_qt_logic
move non-qt specific logic out; add tests
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: cachix/install-nix-action@v27
|
||||
with:
|
||||
extra_nix_config: |
|
||||
experimental-features = nix-command flakes
|
||||
|
||||
- uses: cachix/cachix-action@v15
|
||||
with:
|
||||
name: logos-co
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
|
||||
- name: Build vanilla Qt plugin test
|
||||
run: nix build '.#checks.x86_64-linux.vanilla-plugin'
|
||||
Generated
+2
-60
@@ -1,31 +1,8 @@
|
||||
{
|
||||
"nodes": {
|
||||
"logos-cpp-sdk": {
|
||||
"inputs": {
|
||||
"logos-nix": "logos-nix",
|
||||
"nixpkgs": [
|
||||
"logos-cpp-sdk",
|
||||
"logos-nix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1774988975,
|
||||
"narHash": "sha256-wJ7Bv3TL754bZcTL2qilI0JahiVag7fLDzw8Y6Qz0pk=",
|
||||
"owner": "logos-co",
|
||||
"repo": "logos-cpp-sdk",
|
||||
"rev": "d633575677a3d19a8bf1d5ff687398dace532938",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "logos-co",
|
||||
"repo": "logos-cpp-sdk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"logos-module": {
|
||||
"inputs": {
|
||||
"logos-nix": "logos-nix_2",
|
||||
"logos-nix": "logos-nix",
|
||||
"nixpkgs": [
|
||||
"logos-module",
|
||||
"logos-nix",
|
||||
@@ -68,24 +45,6 @@
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"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_3": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1774455309,
|
||||
"narHash": "sha256-3AN7aFnArdysrbQQ2UskWzjNSFADb4hDCsnx69Fa0ng=",
|
||||
@@ -132,27 +91,10 @@
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"logos-cpp-sdk": "logos-cpp-sdk",
|
||||
"logos-module": "logos-module",
|
||||
"logos-nix": "logos-nix_3",
|
||||
"logos-nix": "logos-nix_2",
|
||||
"nixpkgs": [
|
||||
"logos-nix",
|
||||
"nixpkgs"
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
|
||||
inputs = {
|
||||
logos-nix.url = "github:logos-co/logos-nix";
|
||||
logos-cpp-sdk.url = "github:logos-co/logos-cpp-sdk";
|
||||
# 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";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, logos-cpp-sdk, logos-module, ... }:
|
||||
outputs = { self, nixpkgs, logos-module, ... }:
|
||||
let
|
||||
systems = [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ];
|
||||
|
||||
@@ -17,15 +18,32 @@
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
});
|
||||
|
||||
# Import the backend library
|
||||
backendLib = import ./lib {
|
||||
inherit nixpkgs logos-cpp-sdk logos-module;
|
||||
# Raw backend lib — no deps baked in.
|
||||
# Callers (logos-module-builder) inject logosModule per call.
|
||||
rawLib = import ./lib {
|
||||
inherit nixpkgs;
|
||||
inherit (nixpkgs) lib;
|
||||
backendRoot = ./.;
|
||||
};
|
||||
|
||||
# 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 {
|
||||
# Export the backend library for use by logos-module-builder
|
||||
lib = backendLib;
|
||||
# Default export: wrapped with logosModule pre-filled
|
||||
lib = wrappedLib;
|
||||
|
||||
# Raw export: no deps — for use by logos-module-builder
|
||||
rawLib = rawLib;
|
||||
|
||||
# Provide the cmake module as a package
|
||||
packages = forAllSystems ({ pkgs, ... }: {
|
||||
@@ -36,18 +54,25 @@
|
||||
default = self.packages.${pkgs.system}.cmake-module;
|
||||
});
|
||||
|
||||
# Tests
|
||||
checks = forAllSystems ({ pkgs, ... }: {
|
||||
# Build a vanilla Qt plugin with no Logos SDK deps
|
||||
vanilla-plugin = import ./tests/test-vanilla-plugin.nix {
|
||||
inherit pkgs;
|
||||
backendCommon = rawLib.common;
|
||||
};
|
||||
});
|
||||
|
||||
# Dev shell for working on the backend itself
|
||||
devShells = forAllSystems ({ pkgs, ... }:
|
||||
let
|
||||
logosSdk = logos-cpp-sdk.packages.${pkgs.system}.default;
|
||||
logosModule = logos-module.packages.${pkgs.system}.default;
|
||||
shell = wrappedLib.devShellInputs pkgs;
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
nativeBuildInputs = backendLib.common.commonNativeBuildInputs pkgs;
|
||||
buildInputs = backendLib.common.commonBuildInputs pkgs;
|
||||
nativeBuildInputs = shell.nativeBuildInputs;
|
||||
buildInputs = shell.buildInputs;
|
||||
shellHook = ''
|
||||
export LOGOS_CPP_SDK_ROOT="${logosSdk}"
|
||||
export LOGOS_MODULE_ROOT="${logosModule}"
|
||||
${shell.shellHook}
|
||||
echo "Logos Qt Plugin Backend development environment"
|
||||
'';
|
||||
};
|
||||
|
||||
+8
-3
@@ -1,4 +1,8 @@
|
||||
# Qt-specific utilities for building Logos plugins
|
||||
#
|
||||
# This module only knows about Qt. It does NOT reference logos-cpp-sdk.
|
||||
# The logosModule dependency (interface.h) is the only Logos-specific dep,
|
||||
# and it's passed in by the caller.
|
||||
{ lib }:
|
||||
|
||||
{
|
||||
@@ -29,10 +33,11 @@
|
||||
pkgs.qt6.qtremoteobjects
|
||||
];
|
||||
|
||||
# CMake flags for Qt plugin builds
|
||||
commonCmakeFlags = { logosSdk, logosModule }: [
|
||||
# CMake flags for Qt plugin builds.
|
||||
# Only includes logosModule (for interface.h).
|
||||
# SDK flags are added by the builder layer, not here.
|
||||
commonCmakeFlags = { logosModule }: [
|
||||
"-GNinja"
|
||||
"-DLOGOS_CPP_SDK_ROOT=${logosSdk}"
|
||||
"-DLOGOS_MODULE_ROOT=${logosModule}"
|
||||
];
|
||||
|
||||
|
||||
+30
-29
@@ -1,16 +1,16 @@
|
||||
# Logos Qt Plugin Backend
|
||||
#
|
||||
# This module exports the backend interface that logos-module-builder uses
|
||||
# to build Qt 6 plugins. It encapsulates all Qt-specific build logic:
|
||||
# CMake configuration, Qt dependencies, code generation, and header generation.
|
||||
# Builds Logos modules as Qt 6 plugins. Encapsulates Qt-specific build logic:
|
||||
# CMake configuration, Qt dependencies, plugin compilation, and macOS fixups.
|
||||
#
|
||||
# Backend interface:
|
||||
# buildPlugin — compile sources + metadata → Qt plugin .so/.dylib
|
||||
# buildHeaders — introspect compiled plugin → SDK headers for consumers
|
||||
# devShellInputs — Qt-specific dev shell dependencies
|
||||
# common — Qt-specific utilities (deps, cmake flags, platform helpers)
|
||||
# This backend does NOT know about logos-cpp-sdk. It only knows about:
|
||||
# - Qt (cmake, ninja, qtbase, qtremoteobjects)
|
||||
# - logosModule (interface.h — the plugin interface contract)
|
||||
#
|
||||
{ nixpkgs, logos-cpp-sdk, logos-module, lib, backendRoot }:
|
||||
# The logos-cpp-sdk (generator, SDK lib, headers) is added by the caller
|
||||
# (logos-module-builder) via extraNativeBuildInputs / extraBuildInputs / env.
|
||||
#
|
||||
{ nixpkgs, lib, backendRoot }:
|
||||
|
||||
let
|
||||
common = import ./common.nix { inherit lib; };
|
||||
@@ -19,52 +19,56 @@ let
|
||||
|
||||
in {
|
||||
# Build a Qt plugin from sources.
|
||||
# Returns: derivation with lib/{name}_plugin.so and include/ (general SDK headers)
|
||||
# logosModule provides interface.h. Everything else (SDK, generator) comes
|
||||
# via extraNativeBuildInputs/extraBuildInputs passed by the caller.
|
||||
# Returns: derivation with lib/{name}_plugin.so
|
||||
buildPlugin = {
|
||||
pkgs,
|
||||
src,
|
||||
config,
|
||||
logosModule,
|
||||
moduleDeps ? {},
|
||||
externalLibs ? {},
|
||||
extraNativeBuildInputs ? [],
|
||||
extraBuildInputs ? [],
|
||||
extraCmakeFlags ? [],
|
||||
extraEnv ? {},
|
||||
preConfigure ? "",
|
||||
postInstall ? "",
|
||||
}:
|
||||
let
|
||||
logosSdk = logos-cpp-sdk.packages.${pkgs.system}.default;
|
||||
logosModule = logos-module.packages.${pkgs.system}.default;
|
||||
commonArgs = {
|
||||
pname = "logos-${config.name}-module";
|
||||
version = config.version;
|
||||
nativeBuildInputs = common.commonNativeBuildInputs pkgs ++ [ logosSdk ] ++ extraNativeBuildInputs;
|
||||
nativeBuildInputs = common.commonNativeBuildInputs pkgs ++ extraNativeBuildInputs;
|
||||
buildInputs = common.commonBuildInputs pkgs ++ extraBuildInputs;
|
||||
cmakeFlags = common.commonCmakeFlags { inherit logosSdk logosModule; };
|
||||
cmakeFlags = common.commonCmakeFlags { inherit logosModule; } ++ extraCmakeFlags;
|
||||
env = {
|
||||
LOGOS_CPP_SDK_ROOT = "${logosSdk}";
|
||||
LOGOS_MODULE_ROOT = "${logosModule}";
|
||||
# Keep LOGOS_MODULE_BUILDER_ROOT for backward compatibility with existing CMakeLists.txt
|
||||
LOGOS_MODULE_BUILDER_ROOT = "${backendRoot}";
|
||||
};
|
||||
} // extraEnv;
|
||||
meta = with lib; {
|
||||
description = config.description;
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
};
|
||||
in mkBuildPlugin.build {
|
||||
inherit pkgs src config commonArgs logosSdk moduleDeps externalLibs preConfigure postInstall;
|
||||
inherit pkgs src config commonArgs moduleDeps externalLibs preConfigure postInstall;
|
||||
logosSdk = null; # not used by buildPlugin.nix directly, kept for compat
|
||||
};
|
||||
|
||||
# Generate SDK headers from a compiled plugin.
|
||||
# Returns: derivation with include/*.h (module-specific API headers for consumers)
|
||||
# This is a thin wrapper — the actual generator binary and SDK package
|
||||
# are passed in by the caller.
|
||||
# Returns: derivation with include/*.h
|
||||
buildHeaders = {
|
||||
pkgs,
|
||||
src,
|
||||
config,
|
||||
pluginLib,
|
||||
logosSdk,
|
||||
}:
|
||||
let
|
||||
logosSdk = logos-cpp-sdk.packages.${pkgs.system}.default;
|
||||
commonArgs = {
|
||||
pname = "logos-${config.name}-module";
|
||||
version = config.version;
|
||||
@@ -78,18 +82,15 @@ in {
|
||||
lib = pluginLib;
|
||||
};
|
||||
|
||||
# Dev shell dependencies for modules using this backend.
|
||||
# Returns: { nativeBuildInputs, buildInputs, shellHook }
|
||||
devShellInputs = pkgs:
|
||||
let
|
||||
logosSdk = logos-cpp-sdk.packages.${pkgs.system}.default;
|
||||
logosModule = logos-module.packages.${pkgs.system}.default;
|
||||
in {
|
||||
# Dev shell dependencies — Qt only.
|
||||
# SDK env vars are added by the caller (logos-module-builder).
|
||||
devShellInputs = pkgs: {
|
||||
logosModule ? null,
|
||||
}: {
|
||||
nativeBuildInputs = common.commonNativeBuildInputs pkgs;
|
||||
buildInputs = common.commonBuildInputs pkgs;
|
||||
shellHook = ''
|
||||
export LOGOS_CPP_SDK_ROOT="${logosSdk}"
|
||||
export LOGOS_MODULE_ROOT="${logosModule}"
|
||||
${if logosModule != null then ''export LOGOS_MODULE_ROOT="${logosModule}"'' else ""}
|
||||
export LOGOS_MODULE_BUILDER_ROOT="${backendRoot}"
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
# Integration test: build a vanilla Qt plugin using only Qt deps (no logos-cpp-sdk).
|
||||
# Proves the backend can compile a .so without any Logos SDK dependency.
|
||||
{ pkgs, backendCommon }:
|
||||
|
||||
let
|
||||
pluginSrc = ./vanilla-plugin;
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
pname = "logos-plugin-qt-vanilla-test";
|
||||
version = "0.0.1";
|
||||
|
||||
src = pluginSrc;
|
||||
|
||||
nativeBuildInputs = backendCommon.commonNativeBuildInputs pkgs;
|
||||
buildInputs = backendCommon.commonBuildInputs pkgs;
|
||||
|
||||
dontUseCmakeConfigure = true;
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake .. -GNinja
|
||||
ninja
|
||||
cd ..
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
|
||||
# Verify the plugin .so was created
|
||||
PLUGIN="build/vanilla_test_plugin.so"
|
||||
if [ ! -f "$PLUGIN" ]; then
|
||||
PLUGIN="build/vanilla_test_plugin.dylib"
|
||||
fi
|
||||
|
||||
if [ ! -f "$PLUGIN" ]; then
|
||||
echo "FAIL: Plugin binary not found"
|
||||
ls -la build/
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "OK: Plugin binary exists at $PLUGIN"
|
||||
echo "Size: $(stat -c%s "$PLUGIN" 2>/dev/null || stat -f%z "$PLUGIN") bytes"
|
||||
|
||||
# Verify it's a valid shared library
|
||||
file "$PLUGIN" | grep -q "shared object\|dynamically linked\|Mach-O" || {
|
||||
echo "FAIL: Plugin is not a valid shared library"
|
||||
file "$PLUGIN"
|
||||
exit 1
|
||||
}
|
||||
echo "OK: Plugin is a valid shared library"
|
||||
|
||||
# Verify Qt plugin metadata is embedded
|
||||
if strings "$PLUGIN" | grep -q "vanilla_test"; then
|
||||
echo "OK: Qt plugin metadata found in binary"
|
||||
else
|
||||
echo "FAIL: Qt plugin metadata not found in binary"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/lib
|
||||
cp build/vanilla_test_plugin.* $out/lib/ 2>/dev/null || true
|
||||
echo "Vanilla Qt plugin test passed" > $out/result.txt
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(VanillaTestPlugin LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||
|
||||
# Copy metadata.json to build dir so Q_PLUGIN_METADATA can find it
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.json ${CMAKE_CURRENT_BINARY_DIR}/metadata.json COPYONLY)
|
||||
|
||||
add_library(vanilla_test_plugin SHARED
|
||||
vanilla_test_plugin.h
|
||||
interface.h
|
||||
)
|
||||
|
||||
set_target_properties(vanilla_test_plugin PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "vanilla_test_plugin"
|
||||
)
|
||||
|
||||
target_include_directories(vanilla_test_plugin PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(vanilla_test_plugin PRIVATE Qt6::Core)
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <QtPlugin>
|
||||
#include <QString>
|
||||
|
||||
class PluginInterface {
|
||||
public:
|
||||
virtual ~PluginInterface() = default;
|
||||
virtual QString name() const = 0;
|
||||
virtual QString version() const = 0;
|
||||
};
|
||||
|
||||
#define PluginInterface_iid "com.example.PluginInterface"
|
||||
Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid)
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "vanilla_test",
|
||||
"version": "1.0.0",
|
||||
"description": "Vanilla Qt plugin for testing the backend",
|
||||
"type": "core",
|
||||
"category": "test",
|
||||
"main": "vanilla_test_plugin",
|
||||
"dependencies": []
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
#include "interface.h"
|
||||
|
||||
class VanillaTestPlugin : public QObject, public PluginInterface {
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID PluginInterface_iid FILE "metadata.json")
|
||||
Q_INTERFACES(PluginInterface)
|
||||
public:
|
||||
QString name() const override { return "vanilla_test"; }
|
||||
QString version() const override { return "1.0.0"; }
|
||||
Q_INVOKABLE QString hello() { return "world"; }
|
||||
};
|
||||
Reference in New Issue
Block a user