diff --git a/logos-calc-cpp-ui/flake.lock b/logos-calc-cpp-ui/flake.lock index 608c278..75561d8 100644 --- a/logos-calc-cpp-ui/flake.lock +++ b/logos-calc-cpp-ui/flake.lock @@ -106,7 +106,7 @@ }, "logos-cpp-sdk_10": { "inputs": { - "nixpkgs": "nixpkgs_17" + "nixpkgs": "nixpkgs_16" }, "locked": { "lastModified": 1773672219, @@ -124,7 +124,7 @@ }, "logos-cpp-sdk_11": { "inputs": { - "nixpkgs": "nixpkgs_18" + "nixpkgs": "nixpkgs_17" }, "locked": { "lastModified": 1773672219, @@ -166,7 +166,7 @@ }, "logos-cpp-sdk_3": { "inputs": { - "nixpkgs": "nixpkgs_8" + "nixpkgs": "nixpkgs_7" }, "locked": { "lastModified": 1773672219, @@ -184,7 +184,7 @@ }, "logos-cpp-sdk_4": { "inputs": { - "nixpkgs": "nixpkgs_9" + "nixpkgs": "nixpkgs_8" }, "locked": { "lastModified": 1773672219, @@ -202,7 +202,7 @@ }, "logos-cpp-sdk_5": { "inputs": { - "nixpkgs": "nixpkgs_10" + "nixpkgs": "nixpkgs_9" }, "locked": { "lastModified": 1773672219, @@ -220,7 +220,7 @@ }, "logos-cpp-sdk_6": { "inputs": { - "nixpkgs": "nixpkgs_11" + "nixpkgs": "nixpkgs_10" }, "locked": { "lastModified": 1773672219, @@ -238,7 +238,7 @@ }, "logos-cpp-sdk_7": { "inputs": { - "nixpkgs": "nixpkgs_12" + "nixpkgs": "nixpkgs_11" }, "locked": { "lastModified": 1761230734, @@ -256,7 +256,7 @@ }, "logos-cpp-sdk_8": { "inputs": { - "nixpkgs": "nixpkgs_13" + "nixpkgs": "nixpkgs_12" }, "locked": { "lastModified": 1773672219, @@ -274,7 +274,7 @@ }, "logos-cpp-sdk_9": { "inputs": { - "nixpkgs": "nixpkgs_14" + "nixpkgs": "nixpkgs_13" }, "locked": { "lastModified": 1767724329, @@ -322,7 +322,8 @@ "nix-bundle-appimage": "nix-bundle-appimage_2", "nix-bundle-dir": "nix-bundle-dir_4", "nixpkgs": [ - "logos-nix", + "logos-standalone-app", + "logos-cpp-sdk", "nixpkgs" ] }, @@ -658,24 +659,6 @@ "type": "github" } }, - "logos-nix_7": { - "inputs": { - "nixpkgs": "nixpkgs_7" - }, - "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-standalone-app": { "inputs": { "logos-cpp-sdk": "logos-cpp-sdk_3", @@ -704,7 +687,7 @@ "nix-bundle-appimage": { "inputs": { "nix-bundle-dir": "nix-bundle-dir", - "nixpkgs": "nixpkgs_15" + "nixpkgs": "nixpkgs_14" }, "locked": { "lastModified": 1772047346, @@ -723,7 +706,7 @@ "nix-bundle-appimage_2": { "inputs": { "nix-bundle-dir": "nix-bundle-dir_3", - "nixpkgs": "nixpkgs_19" + "nixpkgs": "nixpkgs_18" }, "locked": { "lastModified": 1772881966, @@ -766,7 +749,7 @@ }, "nix-bundle-dir_2": { "inputs": { - "nixpkgs": "nixpkgs_16" + "nixpkgs": "nixpkgs_15" }, "locked": { "lastModified": 1771971384, @@ -807,7 +790,7 @@ }, "nix-bundle-dir_4": { "inputs": { - "nixpkgs": "nixpkgs_20" + "nixpkgs": "nixpkgs_19" }, "locked": { "lastModified": 1771971384, @@ -904,22 +887,6 @@ } }, "nixpkgs_14": { - "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_15": { "locked": { "lastModified": 1771848320, "narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=", @@ -935,7 +902,7 @@ "type": "github" } }, - "nixpkgs_16": { + "nixpkgs_15": { "locked": { "lastModified": 1770562336, "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", @@ -951,6 +918,22 @@ "type": "github" } }, + "nixpkgs_16": { + "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_17": { "locked": { "lastModified": 1759036355, @@ -969,11 +952,11 @@ }, "nixpkgs_18": { "locked": { - "lastModified": 1759036355, - "narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=", + "lastModified": 1771848320, + "narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127", + "rev": "2fc6539b481e1d2569f25f8799236694180c0993", "type": "github" }, "original": { @@ -985,11 +968,11 @@ }, "nixpkgs_19": { "locked": { - "lastModified": 1771848320, - "narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=", + "lastModified": 1770562336, + "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2fc6539b481e1d2569f25f8799236694180c0993", + "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", "type": "github" }, "original": { @@ -1015,22 +998,6 @@ "type": "github" } }, - "nixpkgs_20": { - "locked": { - "lastModified": 1770562336, - "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_3": { "locked": { "lastModified": 1759036355, @@ -1147,12 +1114,7 @@ "inputs": { "calc_module": "calc_module", "logos-module-builder": "logos-module-builder_2", - "logos-nix": "logos-nix_7", - "logos-standalone-app": "logos-standalone-app", - "nixpkgs": [ - "logos-nix", - "nixpkgs" - ] + "logos-standalone-app": "logos-standalone-app" } } }, diff --git a/logos-calc-cpp-ui/flake.nix b/logos-calc-cpp-ui/flake.nix index 2f86ab9..3d399d0 100644 --- a/logos-calc-cpp-ui/flake.nix +++ b/logos-calc-cpp-ui/flake.nix @@ -7,12 +7,11 @@ calc_module.url = "github:logos-co/logos-tutorial?dir=logos-calc-module"; }; - outputs = { logos-module-builder, logos-standalone-app, calc_module, ... }: + outputs = inputs@{ logos-module-builder, logos-standalone-app, calc_module, ... }: logos-module-builder.lib.mkLogosModule { src = ./.; - configFile = ./module.yaml; - moduleInputs = { inherit calc_module; }; + configFile = ./metadata.json; + flakeInputs = inputs; logosStandalone = logos-standalone-app; - iconFiles = [ ./icons/calc.png ]; }; } diff --git a/logos-calc-cpp-ui/metadata.json b/logos-calc-cpp-ui/metadata.json index ddedbde..75abdf8 100644 --- a/logos-calc-cpp-ui/metadata.json +++ b/logos-calc-cpp-ui/metadata.json @@ -1,10 +1,24 @@ { "name": "calc_ui_cpp", "version": "1.0.0", - "description": "Calculator C++ UI — widget frontend for calc_module", "type": "ui", - "main": "calc_ui_cpp_plugin", - "dependencies": ["calc_module"], "category": "tools", - "icon": "icons/calc.png" + "description": "Calculator C++ UI — widget frontend for calc_module", + "main": "calc_ui_cpp_plugin", + "icon": "icons/calc.png", + "dependencies": ["calc_module"], + + "nix": { + "packages": { + "build": [], + "runtime": [] + }, + "external_libraries": [], + "cmake": { + "find_packages": [], + "extra_sources": [], + "extra_include_dirs": [], + "extra_link_libraries": [] + } + } } diff --git a/logos-calc-cpp-ui/module.yaml b/logos-calc-cpp-ui/module.yaml deleted file mode 100644 index b3e3b98..0000000 --- a/logos-calc-cpp-ui/module.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: calc_ui_cpp -version: 1.0.0 -type: ui -category: tools -description: "Calculator C++ UI — widget frontend for calc_module" - -dependencies: - - calc_module - -nix_packages: - build: [] - runtime: [] - -external_libraries: [] - -cmake: - find_packages: [] - extra_sources: [] - proto_files: [] diff --git a/logos-calc-cpp-ui/src/calc_backend.h b/logos-calc-cpp-ui/src/calc_backend.h index 9b9b022..cd201ae 100644 --- a/logos-calc-cpp-ui/src/calc_backend.h +++ b/logos-calc-cpp-ui/src/calc_backend.h @@ -3,7 +3,7 @@ #include #include -#include "logos_sdk.h" // generated at build time from module.yaml dependencies +#include "logos_sdk.h" // generated at build time from metadata.json dependencies class LogosAPI; diff --git a/logos-calc-module/flake.lock b/logos-calc-module/flake.lock index 8ec1cf7..703653d 100644 --- a/logos-calc-module/flake.lock +++ b/logos-calc-module/flake.lock @@ -127,24 +127,6 @@ "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" - } - }, "nixpkgs": { "locked": { "lastModified": 1759036355, @@ -193,30 +175,9 @@ "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" - } - }, "root": { "inputs": { - "logos-module-builder": "logos-module-builder", - "logos-nix": "logos-nix_4", - "nixpkgs": [ - "logos-nix", - "nixpkgs" - ] + "logos-module-builder": "logos-module-builder" } } }, diff --git a/logos-calc-module/flake.nix b/logos-calc-module/flake.nix index 3cf31e6..0451b40 100644 --- a/logos-calc-module/flake.nix +++ b/logos-calc-module/flake.nix @@ -5,9 +5,10 @@ logos-module-builder.url = "github:logos-co/logos-module-builder"; }; - outputs = { logos-module-builder, ... }: + outputs = inputs@{ logos-module-builder, ... }: logos-module-builder.lib.mkLogosModule { src = ./.; - configFile = ./module.yaml; + configFile = ./metadata.json; + flakeInputs = inputs; }; } diff --git a/logos-calc-module/metadata.json b/logos-calc-module/metadata.json index f9720ec..819669b 100644 --- a/logos-calc-module/metadata.json +++ b/logos-calc-module/metadata.json @@ -1,10 +1,28 @@ { "name": "calc_module", "version": "1.0.0", - "description": "Calculator module wrapping libcalc C library", - "author": "", "type": "core", "category": "general", + "description": "Calculator module wrapping libcalc C library", "main": "calc_module_plugin", - "dependencies": [] + "dependencies": [], + + "nix": { + "packages": { + "build": [], + "runtime": [] + }, + "external_libraries": [ + { + "name": "calc", + "vendor_path": "lib" + } + ], + "cmake": { + "find_packages": [], + "extra_sources": [], + "extra_include_dirs": ["lib"], + "extra_link_libraries": [] + } + } } diff --git a/logos-calc-module/module.yaml b/logos-calc-module/module.yaml deleted file mode 100644 index ca5e3d9..0000000 --- a/logos-calc-module/module.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: calc_module -version: 1.0.0 -type: core -category: general -description: "Calculator module wrapping libcalc C library" - -dependencies: [] - -nix_packages: - build: [] - runtime: [] - -# This tells the builder that "libcalc" is a pre-built library in lib/ -external_libraries: - - name: calc - vendor_path: "lib" - -cmake: - find_packages: [] - extra_sources: [] - extra_include_dirs: - - lib - extra_link_libraries: [] diff --git a/logos-calc-ui/flake.lock b/logos-calc-ui/flake.lock index a4643ed..deaa98f 100644 --- a/logos-calc-ui/flake.lock +++ b/logos-calc-ui/flake.lock @@ -910,11 +910,7 @@ "root": { "inputs": { "logos-module-builder": "logos-module-builder", - "logos-standalone-app": "logos-standalone-app", - "nixpkgs": [ - "logos-module-builder", - "nixpkgs" - ] + "logos-standalone-app": "logos-standalone-app" } } }, diff --git a/logos-calc-ui/flake.nix b/logos-calc-ui/flake.nix index 56c4d70..e9ff4fc 100644 --- a/logos-calc-ui/flake.nix +++ b/logos-calc-ui/flake.nix @@ -3,22 +3,15 @@ inputs = { logos-module-builder.url = "github:logos-co/logos-module-builder"; - nixpkgs.follows = "logos-module-builder/nixpkgs"; - logos-standalone-app.url = "github:logos-co/logos-standalone-app"; + calc_module.url = "github:logos-co/logos-tutorial?dir=logos-calc-module"; }; - outputs = { logos-module-builder, logos-standalone-app, nixpkgs, ... }: { - apps = nixpkgs.lib.genAttrs - [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ] - (system: { - default = logos-module-builder.lib.mkStandaloneApp { - pkgs = import nixpkgs { inherit system; }; - standalone = logos-standalone-app.packages.${system}.default; - qmlSrc = ./.; - metadataFile = ./metadata.json; - format = "qml"; - }; - }); - }; + outputs = inputs@{ logos-module-builder, logos-standalone-app, ... }: + logos-module-builder.lib.mkLogosQmlModule { + src = ./.; + configFile = ./metadata.json; + flakeInputs = inputs; + logosStandalone = logos-standalone-app; + }; } diff --git a/logos-calc-ui/metadata.json b/logos-calc-ui/metadata.json index e6aed2d..4ef141a 100644 --- a/logos-calc-ui/metadata.json +++ b/logos-calc-ui/metadata.json @@ -1,10 +1,24 @@ { "name": "calc_ui", "version": "1.0.0", - "description": "Calculator UI - QML frontend for the calc_module", "type": "ui_qml", - "main": "Main.qml", - "dependencies": ["calc_module"], "category": "tools", - "icon": "icons/calc.png" + "description": "Calculator UI - QML frontend for the calc_module", + "main": "Main.qml", + "icon": "icons/calc.png", + "dependencies": ["calc_module"], + + "nix": { + "packages": { + "build": [], + "runtime": [] + }, + "external_libraries": [], + "cmake": { + "find_packages": [], + "extra_sources": [], + "extra_include_dirs": [], + "extra_link_libraries": [] + } + } } diff --git a/logos-developer-guide.md b/logos-developer-guide.md index ff3b774..66fe56b 100644 --- a/logos-developer-guide.md +++ b/logos-developer-guide.md @@ -10,7 +10,7 @@ A comprehensive guide to creating, building, testing, packaging, and distributin - [Part 1: Creating a Module](#part-1-creating-a-module) - [1.1 Scaffold with logos-module-builder](#11-scaffold-with-logos-module-builder) - [1.2 Project Structure](#12-project-structure) - - [1.3 The module.yaml Configuration](#13-the-moduleyaml-configuration) + - [1.3 The metadata.json Configuration](#13-the-metadatajson-configuration) - [1.4 Writing Module Code](#14-writing-module-code) - [1.5 Building Your Module](#15-building-your-module) - [Part 2: Inspecting and Testing Your Module](#part-2-inspecting-and-testing-your-module) @@ -145,40 +145,44 @@ After scaffolding, your module directory looks like this: ``` logos-my-module/ ├── flake.nix # Nix flake (build config, ~15 lines) -├── module.yaml # Declarative module configuration (~30 lines) +├── metadata.json # Single source of truth: module metadata + build config (~30 lines) ├── CMakeLists.txt # CMake build file (~25 lines) -├── metadata.json # Auto-generated at build time from module.yaml └── src/ ├── my_module_interface.h # Qt interface definition ├── my_module_plugin.h # Plugin header └── my_module_plugin.cpp # Plugin implementation ``` -The key insight: **logos-module-builder** reduces ~600 lines of configuration across 5+ files down to ~70 lines across 2-3 files. +The key insight: **logos-module-builder** reduces ~600 lines of configuration across 5+ files down to ~70 lines across 2-3 files. `metadata.json` serves as the single source of truth — it contains both the runtime metadata (embedded into the plugin binary by Qt) and the build configuration (read by the builder via the `nix` section). -### 1.3 The module.yaml Configuration +### 1.3 The metadata.json Configuration -The `module.yaml` file is the central configuration for your module: +The `metadata.json` file is the single source of truth for your module. It contains both the runtime metadata and the build configuration (read by `logos-module-builder` via the `nix` section). -```yaml -name: my_module -version: 1.0.0 -type: core -category: general -description: "My first Logos module" -dependencies: [] +```json +{ + "name": "my_module", + "version": "1.0.0", + "type": "core", + "category": "general", + "description": "My first Logos module", + "main": "my_module_plugin", + "dependencies": [], -# Nix packages needed at build/runtime (optional) -nix_packages: - build: [] - runtime: [] - -# CMake configuration (optional) -cmake: - find_packages: [] - extra_sources: [] - extra_include_dirs: [] - extra_link_libraries: [] + "nix": { + "packages": { + "build": [], + "runtime": [] + }, + "external_libraries": [], + "cmake": { + "find_packages": [], + "extra_sources": [], + "extra_include_dirs": [], + "extra_link_libraries": [] + } + } +} ``` **Field reference:** @@ -187,16 +191,18 @@ cmake: |-------|----------|---------|-------------| | `name` | Yes | -- | Module name (used for filenames and identifiers) | | `version` | No | `1.0.0` | Semantic version | -| `type` | No | `core` | Module type | +| `type` | No | `core` | Module type (`core`, `ui`, `ui_qml`) | | `category` | No | `general` | Category (general, network, chat, wallet, integration) | | `description` | No | `"A Logos module"` | Human-readable description | +| `main` | Yes | -- | Plugin entry point (plugin name for core/ui, `Main.qml` for QML) | | `dependencies` | No | `[]` | Other Logos module names this depends on | -| `nix_packages.build` | No | `[]` | Nix packages for build time | -| `nix_packages.runtime` | No | `[]` | Nix packages for runtime | -| `cmake.find_packages` | No | `[]` | CMake `find_package()` calls | -| `cmake.extra_sources` | No | `[]` | Additional source files to compile | -| `cmake.extra_include_dirs` | No | `[]` | Additional include directories | -| `cmake.extra_link_libraries` | No | `[]` | Additional libraries to link | +| `nix.packages.build` | No | `[]` | Nix packages for build time | +| `nix.packages.runtime` | No | `[]` | Nix packages for runtime | +| `nix.external_libraries` | No | `[]` | External C/C++ libraries to link | +| `nix.cmake.find_packages` | No | `[]` | CMake `find_package()` calls | +| `nix.cmake.extra_sources` | No | `[]` | Additional source files to compile | +| `nix.cmake.extra_include_dirs` | No | `[]` | Additional include directories | +| `nix.cmake.extra_link_libraries` | No | `[]` | Additional libraries to link | ### 1.4 Writing Module Code @@ -302,7 +308,7 @@ int MyModulePlugin::compute(int a, int b) - Every `Q_INVOKABLE` method is discoverable and callable by other modules at runtime - `initLogos(LogosAPI*)` is called by the host when your module is loaded -- store the pointer for later use - The `eventResponse` signal is used for event forwarding between modules -- `name()` must match the `name` field in your `module.yaml` / `metadata.json` +- `name()` must match the `name` field in your `metadata.json` ### 1.5 Building Your Module @@ -870,31 +876,60 @@ To create a module that wraps an external C/C++ library, use the external librar nix flake init -t github:logos-co/logos-module-builder#with-external-lib ``` -Then configure the external library in `module.yaml`: +Then configure the external library in the `nix` section of `metadata.json`: -```yaml -name: my_wrapper_module -version: 1.0.0 -description: "Wraps libfoo for Logos" +```json +{ + "name": "my_wrapper_module", + "version": "1.0.0", + "description": "Wraps libfoo for Logos", + "main": "my_wrapper_module_plugin", + "dependencies": [], -external_libraries: - - name: libfoo - flake_input: "github:example/libfoo" - output_pattern: "lib/libfoo.*" + "nix": { + "external_libraries": [ + { + "name": "libfoo", + "flake_input": "github:example/libfoo", + "output_pattern": "lib/libfoo.*" + } + ] + } +} +``` -# Or for a vendored library: -external_libraries: - - name: libfoo - vendor_path: "vendor/libfoo" - build_command: "make" - output_pattern: "build/lib/libfoo.*" +For a vendored library, use `vendor_path` and `build_command`: -# Or for a Go library: -external_libraries: - - name: libfoo - vendor_path: "vendor/libfoo" - go_build: true - output_pattern: "libfoo.*" +```json +{ + "nix": { + "external_libraries": [ + { + "name": "libfoo", + "vendor_path": "vendor/libfoo", + "build_command": "make", + "output_pattern": "build/lib/libfoo.*" + } + ] + } +} +``` + +For a Go library with C bindings: + +```json +{ + "nix": { + "external_libraries": [ + { + "name": "libfoo", + "vendor_path": "vendor/libfoo", + "go_build": true, + "output_pattern": "libfoo.*" + } + ] + } +} ``` The builder handles downloading, building, and linking the external library into your module. @@ -1008,16 +1043,7 @@ QML modules are sandboxed: no network access, no filesystem access outside the m ### 7.4 Module Dependencies -Declare dependencies in your `module.yaml`: - -```yaml -name: my_module -dependencies: - - package_manager - - waku_module -``` - -Or in `metadata.json`: +Declare dependencies in your `metadata.json`: ```json { @@ -1026,6 +1052,8 @@ Or in `metadata.json`: } ``` +Each entry in `dependencies` must match the `name` field in that module's own `metadata.json`. When adding a dependency as a flake input, the **input attribute name** must also match the dependency name — e.g., `waku_module.url = "github:logos-co/logos-waku-module"`. The URL can point to any repo, but the attribute name is how the builder resolves dependencies. + When your module is installed via `lgpm`, its dependencies are automatically resolved and installed first. When loaded via `logos-basecamp`, core module dependencies are loaded before your module. --- diff --git a/tutorial-cpp-ui-app.md b/tutorial-cpp-ui-app.md index 8132948..5664617 100644 --- a/tutorial-cpp-ui-app.md +++ b/tutorial-cpp-ui-app.md @@ -57,7 +57,6 @@ This gives you: ``` logos-calc-ui-cpp/ ├── flake.nix -├── module.yaml ├── metadata.json ├── CMakeLists.txt └── src/ @@ -76,49 +75,42 @@ mv src/ui_example_plugin.cpp src/calc_ui_cpp_plugin.cpp --- -## Step 2: `module.yaml` +## Step 2: `metadata.json` -```yaml -name: calc_ui_cpp -version: 1.0.0 -type: ui -category: tools -description: "Calculator C++ UI — widget frontend for calc_module" - -dependencies: - - calc_module - -nix_packages: - build: [] - runtime: [] - -external_libraries: [] - -cmake: - find_packages: [] - extra_sources: [] - proto_files: [] -``` - ---- - -## Step 3: `metadata.json` +`metadata.json` is the single source of truth — it contains both the runtime metadata (embedded into the plugin binary by Qt) and the build configuration (read by `logos-module-builder` via the `nix` section). ```json { "name": "calc_ui_cpp", "version": "1.0.0", - "description": "Calculator C++ UI — widget frontend for calc_module", "type": "ui", + "category": "tools", + "description": "Calculator C++ UI — widget frontend for calc_module", "main": "calc_ui_cpp_plugin", + "icon": "icons/calc.png", "dependencies": ["calc_module"], - "category": "tools" + + "nix": { + "packages": { + "build": [], + "runtime": [] + }, + "external_libraries": [], + "cmake": { + "find_packages": [], + "extra_sources": [], + "extra_include_dirs": [], + "extra_link_libraries": [] + } + } } ``` +> **Naming convention:** Each entry in `dependencies` must match the `name` field in that module's own `metadata.json`. When adding a dependency as a flake input, the **input attribute name** must also match — e.g., `calc_module.url = "github:logos-co/logos-tutorial?dir=logos-calc-module"`. The URL can point to any repo, but the attribute name is how the builder resolves dependencies. + --- -## Step 4: `CMakeLists.txt` +## Step 3: `CMakeLists.txt` ```cmake cmake_minimum_required(VERSION 3.14) @@ -144,11 +136,11 @@ find_package(Qt6 REQUIRED COMPONENTS Widgets) target_link_libraries(calc_ui_cpp_module_plugin PRIVATE Qt6::Widgets) ``` -> For Option A (QML inside the plugin) you will add `Quick QuickWidgets` and `qt_add_resources` — covered in [Step 7](#step-7-option-a--qml-loaded-from-c). +> For Option A (QML inside the plugin) you will add `Quick QuickWidgets` and `qt_add_resources` — covered in [Step 6](#step-6-option-a--qml-loaded-from-c). --- -## Step 5: Interface Header (`src/calc_ui_cpp_interface.h`) +## Step 4: Interface Header (`src/calc_ui_cpp_interface.h`) ```cpp #ifndef CALC_UI_CPP_INTERFACE_H @@ -170,13 +162,13 @@ Q_DECLARE_INTERFACE(CalcUiCppInterface, CalcUiCppInterface_iid) --- -## Step 6: Backend Class +## Step 5: Backend Class -The backend class is the key addition over the QML plugin. It holds a `LogosModules*` wrapper — a typed C++ SDK generated at build time from `module.yaml` — and exposes `Q_INVOKABLE` methods that call `calc_module` through it. Because the calls go through a generated typed class, argument types are preserved — no `QString`/`int` coercion issues. +The backend class is the key addition over the QML plugin. It holds a `LogosModules*` wrapper — a typed C++ SDK generated at build time from `metadata.json` — and exposes `Q_INVOKABLE` methods that call `calc_module` through it. Because the calls go through a generated typed class, argument types are preserved — no `QString`/`int` coercion issues. ### How the generated SDK works -When `module.yaml` declares `dependencies: [calc_module]` and `calc_module` is passed as a flake input via `moduleInputs`, the build system runs `logos-cpp-generator` before compilation. This produces: +When `metadata.json` declares `"dependencies": ["calc_module"]` and `calc_module` is passed as a flake input via `flakeInputs`, the build system runs `logos-cpp-generator` before compilation. This produces: - `logos_sdk.h` / `logos_sdk.cpp` — the `LogosModules` umbrella class with one typed member per dependency - `calc_module_api.h` / `calc_module_api.cpp` — the per-module wrapper included by `logos_sdk.h` @@ -197,7 +189,7 @@ This is the same pattern used in production modules such as `logos-storage-ui`. #include #include -#include "logos_sdk.h" // generated at build time from module.yaml dependencies +#include "logos_sdk.h" // generated at build time from metadata.json dependencies class LogosAPI; @@ -240,11 +232,11 @@ QString CalcBackend::libVersion() { return m_logos->calc_module.libVer --- -## Step 7: Option A — QML Loaded from C++ +## Step 6: Option A — QML Loaded from C++ The plugin loads `src/qml/Main.qml` into a `QQuickWidget` and exposes `CalcBackend` as a QML context property. The QML is identical in structure to `logos-calc-ui/Main.qml` (Part 2), but calls `backend.*` methods directly instead of routing through the `logos.callModule()` IPC bridge — so argument types are preserved and there is no sandboxing overhead. -### 7.1 Add the QML file +### 6.1 Add the QML file Create `src/qml/Main.qml`. The structure mirrors `logos-calc-ui/Main.qml` exactly; the only difference is that buttons call `backend.*` methods directly instead of routing through `logos.callModule(...)`: @@ -322,7 +314,7 @@ Item { } ``` -### 7.2 Update `CMakeLists.txt` +### 6.2 Update `CMakeLists.txt` Add `Quick` and `QuickWidgets`, and embed the QML as a Qt resource: @@ -360,7 +352,7 @@ qt_add_resources(calc_ui_cpp_module_plugin "qml_resources" ) ``` -### 7.3 `createWidget()` — load QML +### 6.3 `createWidget()` — load QML Replace `calc_ui_cpp_plugin.cpp` with: @@ -414,7 +406,7 @@ void CalcUiCppPlugin::destroyWidget(QWidget* widget) } ``` -### 7.4 Dev Mode +### 6.4 Dev Mode When `QML_PATH` is set, the plugin loads `Main.qml` from disk instead of the embedded resource. You can edit QML layout, styling, and property bindings without a Nix rebuild — just restart the app to pick up changes. @@ -427,14 +419,14 @@ QML_PATH=$PWD/src/qml \ > **What still requires a rebuild:** > - Changes to `.cpp` / `.h` files (backend logic, plugin interface) -> - Changes to `CMakeLists.txt` or `module.yaml` +> - Changes to `CMakeLists.txt` or `metadata.json` > > **What does not require a rebuild:** > - Any `.qml` change — layout, styling, property bindings, JS logic --- -## Step 8: Option B — Pure Qt Widget +## Step 7: Option B — Pure Qt Widget The plugin creates a standard Qt widget using layouts and connects button clicks to the backend. No QML, no additional Qt modules — just `Qt6::Widgets`. @@ -577,11 +569,11 @@ void CalcUiCppPlugin::destroyWidget(QWidget* widget) --- -## Step 9: `flake.nix` +## Step 8: `flake.nix` -Pass `standaloneApp` to `mkLogosModule` and you get `apps.default` (i.e. `nix run`) for free — no manual `apps` block required. +Pass `logosStandalone` to `mkLogosModule` and you get `apps.default` (i.e. `nix run`) for free — no manual `apps` block required. -**Important — `moduleInputs`:** Because `module.yaml` declares `dependencies: [calc_module]`, the build system runs `logos-cpp-generator` before compiling your C++ sources. The generator introspects `calc_module`'s built plugin to produce `logos_sdk.h` / `logos_sdk.cpp` (and per-module `calc_module_api.h` / `calc_module_api.cpp`). These are the files your backend includes as `#include "logos_sdk.h"`. For this to work, `calc_module` must be available as a built Nix package at code-generation time — that is what `moduleInputs` provides. Without it, the build fails with `'logos_sdk.h' file not found`. +**Important — `flakeInputs`:** Because `metadata.json` declares `"dependencies": ["calc_module"]`, the build system runs `logos-cpp-generator` before compiling your C++ sources. The generator introspects `calc_module`'s built plugin to produce `logos_sdk.h` / `logos_sdk.cpp` (and per-module `calc_module_api.h` / `calc_module_api.cpp`). These are the files your backend includes as `#include "logos_sdk.h"`. For this to work, `calc_module` must be available as a built Nix package at code-generation time — that is what `flakeInputs` provides (the builder discovers dependency inputs by matching their names against the `dependencies` array in `metadata.json`). Without it, the build fails with `'logos_sdk.h' file not found`. ```nix { @@ -593,24 +585,23 @@ Pass `standaloneApp` to `mkLogosModule` and you get `apps.default` (i.e. `nix ru calc_module.url = "github:logos-co/logos-tutorial?dir=logos-calc-module"; }; - outputs = { logos-module-builder, logos-standalone-app, calc_module, ... }: + outputs = inputs@{ logos-module-builder, logos-standalone-app, calc_module, ... }: logos-module-builder.lib.mkLogosModule { src = ./.; - configFile = ./module.yaml; - moduleInputs = { inherit calc_module; }; + configFile = ./metadata.json; + flakeInputs = inputs; logosStandalone = logos-standalone-app; - iconFiles = [ ./icons/calc.png ]; }; } ``` -`standaloneApp` tells `mkLogosModule` to wire up `apps.default` automatically. It stages the compiled plugin alongside `metadata.json` and any icon files into a Nix store directory, then produces a shell script that calls `logos-standalone-app` with that directory — exactly what `nix run` executes. +`logosStandalone` tells `mkLogosModule` to wire up `apps.default` automatically. It stages the compiled plugin alongside `metadata.json` and any icon files into a Nix store directory, then produces a shell script that calls `logos-standalone-app` with that directory — exactly what `nix run` executes. --- -## Step 10: Build and Test +## Step 9: Build and Test -### 10.1 Build +### 9.1 Build ```bash git add -A @@ -625,7 +616,7 @@ lm ./result/lib/calc_ui_cpp_plugin.dylib You should see `createWidget` and `destroyWidget` in the methods list. -### 10.2 UI only (layout preview) +### 9.2 UI only (layout preview) ```bash nix run . --override-input calc_module path:../logos-calc-module @@ -635,7 +626,7 @@ The widget opens. No backend connected yet, so button clicks will silently retur > **Why `--override-input`?** `calc_module.url` in `flake.nix` points to the published GitHub URL. For local development, `--override-input` redirects it to the local sibling directory. This is the same mechanism `ws build --local` / `ws build --auto-local` uses throughout the workspace. -### 10.3 Full functionality (with modules) +### 9.3 Full functionality (with modules) ```bash nix build 'github:logos-co/logos-package-manager-module#cli' --out-link ./pm @@ -657,9 +648,9 @@ nix run . --override-input calc_module path:../logos-calc-module -- --modules-di --- -## Step 11: Load in `logos-basecamp` +## Step 10: Load in `logos-basecamp` -### 11.1 Create LGX packages +### 10.1 Create LGX packages ```bash # Package calc_module (from Part 1) @@ -671,7 +662,7 @@ cd ../logos-calc-ui-cpp nix bundle --bundler 'github:logos-co/nix-bundle-lgx#portable' '.' -o lgx-calc-ui-cpp ``` -### 11.2 Install via logos-basecamp UI +### 10.2 Install via logos-basecamp UI 1. Open `logos-basecamp` 2. Go to **Package Manager** @@ -681,7 +672,7 @@ nix bundle --bundler 'github:logos-co/nix-bundle-lgx#portable' '.' -o lgx-calc-u The "Calculator" tab appears in the sidebar. -### 11.3 Install via CLI (alternative) +### 10.3 Install via CLI (alternative) ```bash nix build 'github:logos-co/logos-package-manager-module#cli' --out-link ./pm @@ -689,7 +680,7 @@ nix build 'github:logos-co/logos-package-manager-module#cli' --out-link ./pm ./pm/bin/lgpm install --file lgx-calc-ui-cpp/*.lgx ``` -### 11.4 Build logos-basecamp from source +### 10.4 Build logos-basecamp from source Build a local `logos-basecamp` binary, then use `lgpm` to populate a modules directory and run it: diff --git a/tutorial-qml-ui-app.md b/tutorial-qml-ui-app.md index 6d5e993..4e8a0bb 100644 --- a/tutorial-qml-ui-app.md +++ b/tutorial-qml-ui-app.md @@ -82,6 +82,8 @@ Replace the template contents with your plugin's details: The `dependencies` field tells the host to load `calc_module` before showing your UI. +> **Naming convention:** Each entry in `dependencies` must match the `name` field in that module's own `metadata.json`. When adding a dependency as a flake input, the **input attribute name** must also match the dependency name — e.g., `calc_module.url = "github:logos-co/logos-tutorial?dir=logos-calc-module"`. The URL can point to any repo, but the attribute name is how the builder resolves dependencies. + --- ## Step 3: Write `Main.qml` @@ -222,7 +224,7 @@ The `logos` object is injected by the host at runtime. The `callModule` helper c ## Step 4: Update `flake.nix` -The template already has everything wired up. The only change needed is the description: +The template already has everything wired up. Update the description and add `calc_module` as a dependency input: ```nix { @@ -230,28 +232,21 @@ The template already has everything wired up. The only change needed is the desc inputs = { logos-module-builder.url = "github:logos-co/logos-module-builder"; - nixpkgs.follows = "logos-module-builder/nixpkgs"; - logos-standalone-app.url = "github:logos-co/logos-standalone-app"; + calc_module.url = "github:logos-co/logos-tutorial?dir=logos-calc-module"; # must match dependency name in metadata.json }; - outputs = { logos-module-builder, logos-standalone-app, nixpkgs, ... }: { - apps = nixpkgs.lib.genAttrs - [ "aarch64-darwin" "x86_64-darwin" "aarch64-linux" "x86_64-linux" ] - (system: { - default = logos-module-builder.lib.mkStandaloneApp { - pkgs = import nixpkgs { inherit system; }; - standalone = logos-standalone-app.packages.${system}.default; - qmlSrc = ./.; - metadataFile = ./metadata.json; - format = "qml"; - }; - }); - }; + outputs = inputs@{ logos-module-builder, logos-standalone-app, ... }: + logos-module-builder.lib.mkLogosQmlModule { + src = ./.; + configFile = ./metadata.json; + flakeInputs = inputs; + logosStandalone = logos-standalone-app; + }; } ``` -There is no `packages` output — QML modules have no compilation step so there is nothing to build separately. `qmlSrc = ./.` tells `mkStandaloneApp` to copy the entire source directory into a Nix store directory (any number of `.qml` files, subdirectories, assets), then produce a shell script that calls `logos-standalone-app` with it. `nix run .` is the only entry point needed. +`mkLogosQmlModule` handles everything — it stages QML files, metadata, and icons into a plugin directory. `logosStandalone` wires up `apps.default` so `nix run .` launches the UI in a standalone window. `flakeInputs = inputs` passes all inputs so that dependencies declared in `metadata.json` are resolved automatically — note that the input attribute name (`calc_module`) must match the dependency name. --- @@ -462,7 +457,7 @@ nix build 'github:logos-co/logos-package-manager-module#cli' --out-link ./pm | | Core Module (Part 1) | QML UI Plugin (Part 2) | |---|---|---| | Language | C++ | QML / JavaScript | -| Files | `.cpp`, `.h`, `CMakeLists.txt`, `module.yaml` | `Main.qml`, `metadata.json` | +| Files | `.cpp`, `.h`, `CMakeLists.txt`, `metadata.json` | `Main.qml`, `metadata.json` | | Compilation | Yes (CMake → `.so`) | No (file copy) | | `metadata.type` | `"core"` | `"ui_qml"` | | Test command | `logoscore -m ./result/lib -l calc_module` | `nix run .` | diff --git a/tutorial-wrapping-c-library.md b/tutorial-wrapping-c-library.md index 3c045f9..79dafcb 100644 --- a/tutorial-wrapping-c-library.md +++ b/tutorial-wrapping-c-library.md @@ -25,7 +25,7 @@ This tutorial walks you through wrapping a C shared library (`.so` on Linux, `.d ## Step 1: Scaffold the Module Project -Before writing any C code, scaffold the Logos module project using the official template. This gives you the correct `flake.nix`, `module.yaml`, directory structure, and build configuration out of the box. +Before writing any C code, scaffold the Logos module project using the official template. This gives you the correct `flake.nix`, `metadata.json`, directory structure, and build configuration out of the box. ### 1.1 Create the project using the module builder template @@ -38,7 +38,7 @@ nix flake init -t github:logos-co/logos-module-builder#with-external-lib # nix flake init -t github:logos-co/logos-module-builder ``` -This generates the skeleton files (`flake.nix`, `module.yaml`, `CMakeLists.txt`, etc.) pre-configured for the logos-module-builder. You then customize them for your specific library. +This generates the skeleton files (`flake.nix`, `metadata.json`, `CMakeLists.txt`, etc.) pre-configured for the logos-module-builder. You then customize them for your specific library. > **Alternative approach:** You can also create the C library as a separate project, build it there, then copy the resulting `.so`/`.dylib` and header files into the module's `lib/` directory. This can be cleaner for larger libraries with their own build systems. @@ -177,9 +177,8 @@ If you used the template in Step 1.1, you already have the skeleton files. Now c ``` logos-calc-module/ ├── flake.nix # Nix build configuration (~10 lines) -├── module.yaml # Module metadata and build settings (~20 lines) +├── metadata.json # Module metadata, build settings, and runtime config (~25 lines) ├── CMakeLists.txt # CMake build file (~20 lines) -├── metadata.json # Runtime metadata (~10 lines) ├── lib/ │ ├── libcalc.h # C library header │ ├── libcalc.c # C library source @@ -190,65 +189,52 @@ logos-calc-module/ └── calc_module_plugin.cpp # Plugin implementation (wrapping logic) ``` -### 2.1 `module.yaml` — Module Configuration +### 2.1 `metadata.json` — Module Configuration -This is the central configuration file. It tells `logos-module-builder` what to build and how. - -```yaml -name: calc_module -version: 1.0.0 -type: core -category: general -description: "Calculator module wrapping libcalc C library" - -dependencies: [] - -nix_packages: - build: [] - runtime: [] - -# This tells the builder that "libcalc" is a pre-built library in lib/ -external_libraries: - - name: calc - vendor_path: "lib" - -cmake: - find_packages: [] - extra_sources: [] - extra_include_dirs: - - lib - extra_link_libraries: [] -``` - -**Key fields explained:** - - -| Field | What it does | -| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | Module name — must be a valid C identifier (used in filenames, method calls) | -| `external_libraries[].name` | Library name **without the `lib` prefix** — the builder looks for `lib.so` / `lib.dylib` in the directory specified by `vendor_path`. So `name: calc` matches the file `libcalc.so` / `libcalc.dylib`. This follows the standard Unix library naming convention where `-lcalc` links against `libcalc`. | -| `external_libraries[].vendor_path` | Where to find the pre-built library. `"lib"` means the `lib/` directory in your project root | -| `cmake.extra_include_dirs` | Added to the CMake include path so your C++ code can `#include "lib/libcalc.h"` | - - -### 2.2 `metadata.json` — Runtime Metadata - -This file is embedded into the plugin binary by Qt's `Q_PLUGIN_METADATA` macro: +This is the single source of truth for your module. It is both embedded into the plugin binary by Qt's `Q_PLUGIN_METADATA` macro (for runtime metadata) and read by `logos-module-builder` to configure the Nix build (via the `nix` section). ```json { "name": "calc_module", "version": "1.0.0", - "description": "Calculator module wrapping libcalc C library", - "author": "", "type": "core", "category": "general", + "description": "Calculator module wrapping libcalc C library", "main": "calc_module_plugin", - "dependencies": [] + "dependencies": [], + + "nix": { + "packages": { + "build": [], + "runtime": [] + }, + "external_libraries": [ + { + "name": "calc", + "vendor_path": "lib" + } + ], + "cmake": { + "find_packages": [], + "extra_sources": [], + "extra_include_dirs": ["lib"], + "extra_link_libraries": [] + } + } } ``` -### 2.3 `CMakeLists.txt` — Build File +**Key fields explained:** + + +| Field | What it does | +| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | Module name — must be a valid C identifier (used in filenames, method calls) | +| `nix.external_libraries[].name` | Library name **without the `lib` prefix** — the builder looks for `lib.so` / `lib.dylib` in the directory specified by `vendor_path`. So `name: calc` matches the file `libcalc.so` / `libcalc.dylib`. This follows the standard Unix library naming convention where `-lcalc` links against `libcalc`. | +| `nix.external_libraries[].vendor_path` | Where to find the pre-built library. `"lib"` means the `lib/` directory in your project root | +| `nix.cmake.extra_include_dirs` | Added to the CMake include path so your C++ code can `#include "lib/libcalc.h"` | + +### 2.2 `CMakeLists.txt` — Build File ```cmake cmake_minimum_required(VERSION 3.14) @@ -277,7 +263,7 @@ logos_module( **How `EXTERNAL_LIBS calc` works:** The `logos_module()` CMake function searches `lib/` for `libcalc.so` (Linux) or `libcalc.dylib` (macOS), links it to your plugin, and sets up RPATH so the library is found at runtime. -### 2.4 `flake.nix` — Nix Build Config +### 2.3 `flake.nix` — Nix Build Config ```nix { @@ -285,21 +271,20 @@ logos_module( inputs = { logos-module-builder.url = "github:logos-co/logos-module-builder"; - logos-nix.url = "github:logos-co/logos-nix"; - nixpkgs.follows = "logos-nix/nixpkgs"; }; - outputs = { self, logos-module-builder, nixpkgs }: + outputs = inputs@{ logos-module-builder, ... }: logos-module-builder.lib.mkLogosModule { src = ./.; - configFile = ./module.yaml; + configFile = ./metadata.json; + flakeInputs = inputs; }; } ``` -That's it — `mkLogosModule` handles all the Nix complexity (fetching Qt, the SDK, the code generator, setting up include paths, etc.). +That's it — `mkLogosModule` handles all the Nix complexity (fetching Qt, the SDK, the code generator, setting up include paths, etc.). Note that `configFile` points to `metadata.json` (the single source of truth) and `flakeInputs = inputs` passes all flake inputs to the builder. -### 2.5 `src/calc_module_interface.h` — Interface Declaration +### 2.4 `src/calc_module_interface.h` — Interface Declaration This declares the methods your module exposes. It inherits from `PluginInterface` (provided by the Logos C++ SDK). @@ -335,7 +320,7 @@ Q_DECLARE_INTERFACE(CalcModuleInterface, CalcModuleInterface_iid) - Supported parameter/return types: `int`, `bool`, `QString`, `QByteArray`, `QVariant`, `QJsonArray`, `QStringList`, `LogosResult` - The interface ID string (e.g., `"org.logos.CalcModuleInterface"`) must be unique across all modules -### 2.6 `src/calc_module_plugin.h` — Plugin Header +### 2.5 `src/calc_module_plugin.h` — Plugin Header This is the actual plugin class. It inherits from both `QObject` (for Qt's meta-object system) and your interface. @@ -391,10 +376,10 @@ signals: - `Q_INTERFACES(CalcModuleInterface PluginInterface)` — registers both interfaces with Qt's plugin system - `initLogos` must be `Q_INVOKABLE` but **not** `override` — the base class `PluginInterface` does not declare it as virtual; the Logos host calls it reflectively via `QMetaObject::invokeMethod` - `eventResponse` signal is required for event forwarding between modules -- `name()` must return the same string as the `name` field in `module.yaml` and `metadata.json` +- `name()` must return the same string as the `name` field in `metadata.json` - **No `m_logosAPI` member variable** — the `LogosAPI`* pointer is stored in the global `logosAPI` variable defined in `liblogos`, not in a class member. See the `initLogos` implementation below. -### 2.7 `src/calc_module_plugin.cpp` — Plugin Implementation +### 2.6 `src/calc_module_plugin.cpp` — Plugin Implementation This is where the wrapping happens. Each method calls the corresponding C function. @@ -844,8 +829,6 @@ Instead of pre-building the library and placing it in `lib/`, you can have Nix f inputs = { logos-module-builder.url = "github:logos-co/logos-module-builder"; - logos-nix.url = "github:logos-co/logos-nix"; - nixpkgs.follows = "logos-nix/nixpkgs"; # Fetch the library source (non-flake) libfoo-src = { @@ -854,10 +837,11 @@ Instead of pre-building the library and placing it in `lib/`, you can have Nix f }; }; - outputs = { self, logos-module-builder, nixpkgs, libfoo-src }: + outputs = inputs@{ logos-module-builder, libfoo-src, ... }: logos-module-builder.lib.mkLogosModule { src = ./.; - configFile = ./module.yaml; + configFile = ./metadata.json; + flakeInputs = inputs; # Pass the fetched source to the builder externalLibInputs = { @@ -867,26 +851,38 @@ Instead of pre-building the library and placing it in `lib/`, you can have Nix f } ``` -### module.yaml for flake input +### metadata.json for flake input -```yaml -name: foo_module -version: 1.0.0 -type: core -description: "Module wrapping libfoo" +```json +{ + "name": "foo_module", + "version": "1.0.0", + "type": "core", + "description": "Module wrapping libfoo", + "main": "foo_module_plugin", + "dependencies": [], -external_libraries: - - name: foo - flake_input: "github:example/libfoo" - build_command: "make shared" - output_pattern: "build/libfoo.*" - -cmake: - extra_include_dirs: - - lib + "nix": { + "packages": { "build": [], "runtime": [] }, + "external_libraries": [ + { + "name": "foo", + "flake_input": "github:example/libfoo", + "build_command": "make shared", + "output_pattern": "build/libfoo.*" + } + ], + "cmake": { + "find_packages": [], + "extra_sources": [], + "extra_include_dirs": ["lib"], + "extra_link_libraries": [] + } + } +} ``` -**Key difference:** The `externalLibInputs` key in flake.nix (`foo`) must match the `name` field in `external_libraries` (`foo`). The builder will: +**Key difference:** The `externalLibInputs` key in flake.nix (`foo`) must match the `name` field in `nix.external_libraries` (`foo`). The builder will: 1. Clone the source from the flake input 2. Run `build_command` (`make shared`) @@ -896,14 +892,21 @@ cmake: ### For Go libraries -If the external library is written in Go with C bindings (`cgo`): +If the external library is written in Go with C bindings (`cgo`), set `go_build: true` in the `nix.external_libraries` entry within `metadata.json`: -```yaml -external_libraries: - - name: mygolib - flake_input: "github:example/mygolib" - go_build: true - output_pattern: "libmygolib.*" +```json +{ + "nix": { + "external_libraries": [ + { + "name": "mygolib", + "flake_input": "github:example/mygolib", + "go_build": true, + "output_pattern": "libmygolib.*" + } + ] + } +} ``` Setting `go_build: true` enables the Go toolchain and sets `CGO_ENABLED=1`. @@ -915,7 +918,7 @@ Setting `go_build: true` enables the Go toolchain and sets `CGO_ENABLED=1`. The [logos-libp2p-module](https://github.com/logos-co/logos-libp2p-module) is a production module that wraps the `nim-libp2p` library (compiled to a C shared library). Key files: - `**flake.nix**` — Uses `externalLibInputs` to fetch the nim-libp2p C bindings from a GitHub flake -- `**module.yaml**` — Declares `nim_libp2p` as an external library with `go_build: false` +- `**metadata.json**` — Declares `nim_libp2p` as an external library with `go_build: false` in the `nix` section - `**src/plugin.cpp**` — Wraps ~40 C functions (`libp2p_new`, `libp2p_start`, `libp2p_connect`, `libp2p_dial`, `libp2p_gossipsub_subscribe`, etc.) as `Q_INVOKABLE` methods - `**tests/**` — Qt test suite that exercises every wrapped function