diff --git a/logos-calc-module/CMakeLists.txt b/logos-calc-module/CMakeLists.txt index e796327..1a7469d 100644 --- a/logos-calc-module/CMakeLists.txt +++ b/logos-calc-module/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.14) project(CalcModulePlugin LANGUAGES CXX) -# Include the Logos Module CMake helper +# Include the Logos Module CMake helper (provided by logos-module-builder) if(DEFINED ENV{LOGOS_MODULE_BUILDER_ROOT}) include($ENV{LOGOS_MODULE_BUILDER_ROOT}/cmake/LogosModule.cmake) elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/LogosModule.cmake") diff --git a/logos-calc-module/flake.lock b/logos-calc-module/flake.lock deleted file mode 100644 index f46d117..0000000 --- a/logos-calc-module/flake.lock +++ /dev/null @@ -1,406 +0,0 @@ -{ - "nodes": { - "logos-capability-module": { - "inputs": { - "logos-cpp-sdk": "logos-cpp-sdk_2", - "logos-liblogos": "logos-liblogos_2", - "nixpkgs": [ - "logos-module-builder", - "logos-liblogos", - "logos-capability-module", - "logos-liblogos", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1767809111, - "narHash": "sha256-jehjsB+BpDJlVu3I7x+vFVOdXmy9MDmFTJtRqzFUONo=", - "owner": "logos-co", - "repo": "logos-capability-module", - "rev": "7b35383e0aa4e28a4633ed18a87efb57636939b1", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-capability-module", - "type": "github" - } - }, - "logos-cpp-sdk": { - "inputs": { - "nixpkgs": "nixpkgs" - }, - "locked": { - "lastModified": 1772028960, - "narHash": "sha256-BDWFjaKeoJW8oWDlPphNINt5U3P1xt1z1Y4f9jyC7uU=", - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "rev": "95f763b48d74bcdc63093b05159f43500cab139e", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "type": "github" - } - }, - "logos-cpp-sdk_2": { - "inputs": { - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1761230734, - "narHash": "sha256-CMRUwXH7pJZ1OI6bd/TDDDXKqQ1tQZHQEOOwK8TgYHI=", - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "rev": "4b143922c190df00bb3835441c9f0075cb28283b", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "type": "github" - } - }, - "logos-cpp-sdk_3": { - "inputs": { - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1761230734, - "narHash": "sha256-CMRUwXH7pJZ1OI6bd/TDDDXKqQ1tQZHQEOOwK8TgYHI=", - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "rev": "4b143922c190df00bb3835441c9f0075cb28283b", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "type": "github" - } - }, - "logos-cpp-sdk_4": { - "inputs": { - "nixpkgs": "nixpkgs_4" - }, - "locked": { - "lastModified": 1772028960, - "narHash": "sha256-BDWFjaKeoJW8oWDlPphNINt5U3P1xt1z1Y4f9jyC7uU=", - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "rev": "95f763b48d74bcdc63093b05159f43500cab139e", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "type": "github" - } - }, - "logos-cpp-sdk_5": { - "inputs": { - "nixpkgs": "nixpkgs_5" - }, - "locked": { - "lastModified": 1767724329, - "narHash": "sha256-UPkqxqxbKwU5Dmu00TnjiJVXUmfVylF3p1qziEuYwIE=", - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "rev": "32f1d7080d784ff044d91d076ef2f0c7305d4784", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-cpp-sdk", - "type": "github" - } - }, - "logos-liblogos": { - "inputs": { - "logos-capability-module": "logos-capability-module", - "logos-cpp-sdk": "logos-cpp-sdk_4", - "logos-module": "logos-module", - "nix-bundle-appimage": "nix-bundle-appimage", - "nix-bundle-dir": "nix-bundle-dir_2", - "nixpkgs": [ - "logos-module-builder", - "logos-liblogos", - "logos-cpp-sdk", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1772115748, - "narHash": "sha256-sPdAuYiLOjsulrk+uKMT7EG05ZlGT7OYEpgUh+f0nME=", - "owner": "logos-co", - "repo": "logos-liblogos", - "rev": "07780444deb99f10e600247e3696ba495f2f071a", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-liblogos", - "type": "github" - } - }, - "logos-liblogos_2": { - "inputs": { - "logos-cpp-sdk": "logos-cpp-sdk_3", - "nixpkgs": [ - "logos-module-builder", - "logos-liblogos", - "logos-capability-module", - "logos-liblogos", - "logos-cpp-sdk", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1761845775, - "narHash": "sha256-ulK8xq05ejK6qIgZ7WtWb/MJt2rk5BKfDA2z7mM3wq8=", - "owner": "logos-co", - "repo": "logos-liblogos", - "rev": "a92c2c1268bc70764c8f73c7bce07d21024f5af9", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-liblogos", - "type": "github" - } - }, - "logos-module": { - "inputs": { - "logos-cpp-sdk": "logos-cpp-sdk_5", - "nixpkgs": [ - "logos-module-builder", - "logos-liblogos", - "logos-module", - "logos-cpp-sdk", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1770999556, - "narHash": "sha256-anpsEniGTTwUAwknRxjaT9GP4avHzIsolEHdHDTV9rM=", - "owner": "logos-co", - "repo": "logos-module", - "rev": "d1b35f335f938bb5de21a2a6010f1104075bdb1c", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-module", - "type": "github" - } - }, - "logos-module-builder": { - "inputs": { - "logos-cpp-sdk": "logos-cpp-sdk", - "logos-liblogos": "logos-liblogos", - "nixpkgs": [ - "logos-module-builder", - "logos-cpp-sdk", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1770934129, - "narHash": "sha256-RjeB17MQh4HcS5vKtSrDM/J7fz3K8ZDNpswCGr5JF/k=", - "owner": "logos-co", - "repo": "logos-module-builder", - "rev": "a86eea50450511f4474b35032e5fd218a0f17c3c", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "logos-module-builder", - "type": "github" - } - }, - "nix-bundle-appimage": { - "inputs": { - "nix-bundle-dir": "nix-bundle-dir", - "nixpkgs": "nixpkgs_6" - }, - "locked": { - "lastModified": 1772047346, - "narHash": "sha256-RUsTUxKCxuQ3+D2LfBbK0EX1vF7HNMkpWgOGFfZbrEg=", - "owner": "logos-co", - "repo": "nix-bundle-appimage", - "rev": "4d68437c97ac59c3c70c1b2b116235c434d571a8", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "nix-bundle-appimage", - "type": "github" - } - }, - "nix-bundle-dir": { - "inputs": { - "nixpkgs": [ - "logos-module-builder", - "logos-liblogos", - "nix-bundle-appimage", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1771971384, - "narHash": "sha256-fq0H+sxQhkGN054jdN+ZfHZibbOjHA+KD5SpRH78T1g=", - "owner": "logos-co", - "repo": "nix-bundle-dir", - "rev": "1ecb9662145a1ad84007a970b4bef50a4af159c9", - "type": "github" - }, - "original": { - "owner": "logos-co", - "repo": "nix-bundle-dir", - "type": "github" - } - }, - "nix-bundle-dir_2": { - "inputs": { - "nixpkgs": "nixpkgs_7" - }, - "locked": { - "lastModified": 1771971384, - "narHash": "sha256-fq0H+sxQhkGN054jdN+ZfHZibbOjHA+KD5SpRH78T1g=", - "owner": "logos-co", - "repo": "nix-bundle-dir", - "rev": "1ecb9662145a1ad84007a970b4bef50a4af159c9", - "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_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" - } - }, - "nixpkgs_6": { - "locked": { - "lastModified": 1771848320, - "narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "2fc6539b481e1d2569f25f8799236694180c0993", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_7": { - "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" - } - }, - "root": { - "inputs": { - "logos-module-builder": "logos-module-builder", - "nixpkgs": [ - "logos-module-builder", - "nixpkgs" - ] - } - } - }, - "root": "root", - "version": 7 -} diff --git a/logos-calc-module/lib/libcalc.h b/logos-calc-module/lib/libcalc.h index 8365297..b38246e 100644 --- a/logos-calc-module/lib/libcalc.h +++ b/logos-calc-module/lib/libcalc.h @@ -1,10 +1,3 @@ -/** - * libcalc - A tiny calculator C library - * - * This is a minimal C library used to demonstrate - * wrapping a C library as a Logos module. - */ - #ifndef LIBCALC_H #define LIBCALC_H diff --git a/logos-calc-module/lib/libcalc.so b/logos-calc-module/lib/libcalc.so deleted file mode 100755 index 801d018..0000000 Binary files a/logos-calc-module/lib/libcalc.so and /dev/null differ diff --git a/logos-calc-module/module.yaml b/logos-calc-module/module.yaml index f9f6628..ca5e3d9 100644 --- a/logos-calc-module/module.yaml +++ b/logos-calc-module/module.yaml @@ -10,6 +10,7 @@ nix_packages: build: [] runtime: [] +# This tells the builder that "libcalc" is a pre-built library in lib/ external_libraries: - name: calc vendor_path: "lib" diff --git a/logos-calc-module/src/calc_module_plugin.cpp b/logos-calc-module/src/calc_module_plugin.cpp index 4b2cca8..952de06 100644 --- a/logos-calc-module/src/calc_module_plugin.cpp +++ b/logos-calc-module/src/calc_module_plugin.cpp @@ -15,7 +15,8 @@ CalcModulePlugin::~CalcModulePlugin() void CalcModulePlugin::initLogos(LogosAPI* api) { - m_logosAPI = api; + // IMPORTANT: Use the global `logosAPI` variable from liblogos, NOT a class member. + logosAPI = api; qDebug() << "CalcModulePlugin: LogosAPI initialized"; } diff --git a/logos-calc-module/src/calc_module_plugin.h b/logos-calc-module/src/calc_module_plugin.h index 5d7723e..b8a38a9 100644 --- a/logos-calc-module/src/calc_module_plugin.h +++ b/logos-calc-module/src/calc_module_plugin.h @@ -20,9 +20,12 @@ public: explicit CalcModulePlugin(QObject* parent = nullptr); ~CalcModulePlugin() override; - // PluginInterface + // PluginInterface — required by every module QString name() const override { return "calc_module"; } QString version() const override { return "1.0.0"; } + + // Called by the Logos host when the module is loaded. + // NOT marked override — it is invoked reflectively via QMetaObject. Q_INVOKABLE void initLogos(LogosAPI* api); // CalcModuleInterface — each wraps a libcalc C function @@ -35,8 +38,6 @@ public: signals: void eventResponse(const QString& eventName, const QVariantList& args); -private: - LogosAPI* m_logosAPI = nullptr; }; #endif // CALC_MODULE_PLUGIN_H diff --git a/tutorial-wrapping-c-library.md b/tutorial-wrapping-c-library.md index 6ae0603..bb3eebf 100644 --- a/tutorial-wrapping-c-library.md +++ b/tutorial-wrapping-c-library.md @@ -637,53 +637,28 @@ nix build 'github:logos-co/logos-liblogos' --out-link ./logos ### 5.2 Set up the modules directory -`logoscore` expects modules in subdirectories, each with a `manifest.json`: +`logoscore` expects modules in subdirectories, each with a `manifest.json`. Rather than copying files and writing the manifest manually, use the Nix bundler to create an LGX package and install it with the package manager: ```bash -mkdir -p modules/calc_module +# Bundle the module into an LGX package +nix bundle --bundler 'github:logos-co/nix-bundle-lgx' '.#lib' -o lgx-result -# Linux -cp result/lib/calc_module_plugin.so modules/calc_module/ -cp result/lib/libcalc.so modules/calc_module/ - -# macOS -# cp result/lib/calc_module_plugin.dylib modules/calc_module/ -# cp result/lib/libcalc.dylib modules/calc_module/ +# Install it into a modules directory using the Logos Package Manager +nix build 'github:logos-co/logos-package-manager-module#cli' --out-link ./pm +mkdir -p modules +./pm/bin/lgpm --modules-dir ./modules install --file lgx-result/*.lgx ``` -Create `modules/calc_module/manifest.json`: +This extracts the plugin, external libraries, and manifest into the correct directory structure: -```json -{ - "name": "calc_module", - "version": "1.0.0", - "description": "Calculator module wrapping libcalc C library", - "type": "core", - "main": { - "linux-aarch64": "calc_module_plugin.so", - "linux-x86_64": "calc_module_plugin.so", - "darwin-arm64": "calc_module_plugin.dylib", - "darwin-x86_64": "calc_module_plugin.dylib" - }, - "dependencies": [] -} +``` +modules/calc_module/ +├── calc_module_plugin.dylib # (or .so on Linux) +├── libcalc.dylib # (or .so on Linux) +└── manifest.json # Auto-generated ``` -The `main` object maps platform variant names to the plugin filename. `logoscore` uses this to find the right binary for your OS and architecture. - -### 5.3 Set library path (macOS workaround) - -On macOS, RPATH may not be correctly set in the built plugin (this is a known logos-module-builder issue). If `logoscore` fails to load the module with a "library not found" error, set the library path manually: - -```bash -# macOS only — needed until RPATH is fixed in logos-module-builder -export DYLD_LIBRARY_PATH=result/lib/ - -# Linux equivalent (usually not needed if RPATH is set correctly) -# export LD_LIBRARY_PATH=result/lib/ -``` - -### 5.4 Call methods +### 5.3 Call methods ```bash # Call add(3, 5) @@ -739,39 +714,23 @@ Method call successful. Result: ... ## Step 6: Package for Distribution (Optional) -### 6.1 Build the `lgx` tool +The LGX package created in Step 5.2 is a **local** package — its libraries still reference `/nix/store` paths, so it only works on the machine that built it. To create a **portable** package that can be distributed to other machines, use the `#portable` bundler: ```bash -nix build 'github:logos-co/logos-package#lgx' --out-link ./lgx +nix bundle --bundler 'github:logos-co/nix-bundle-lgx#portable' '.#lib' ``` -### 6.2 Create a package +Portable LGX packages are fully self-contained with no `/nix/store` references at runtime. These are the packages used by the Logos App Package Manager UI and published to [logos-modules](https://github.com/logos-co/logos-modules) releases. -```bash -# Create an empty LGX package -./lgx/bin/lgx create calc_module --name calc_module - -# Add the Linux variant -./lgx/bin/lgx add calc_module.lgx \ - --variant linux-aarch64 \ - --files result/lib/ --main calc_module_plugin.so - -# Or on Mac, to add the Mac variant -./lgx/bin/lgx add calc_module.lgx \ - --variant darwin-arm64 \ - --files result/lib/ --main calc_module_plugin.dylib - -# Verify the package -./lgx/bin/lgx verify calc_module.lgx -``` - -On another machine, install with the Logos Package Manager: +To install a portable package on another machine: ```bash nix build 'github:logos-co/logos-package-manager-module#cli' --out-link ./pm ./pm/bin/lgpm --modules-dir ./modules install --file calc_module.lgx ``` +> **Note:** Local builds of `logoscore` / `logos-app` (via `nix build`) expect **local** `.lgx` packages. Portable builds (via `nix build '.#bin-bundle-dir'`, `.#bin-appimage`, or `.#bin-macos-app`) expect **portable** `.lgx` packages. See the [logos-app README](https://github.com/logos-co/logos-app/blob/master/README.md) for details. + --- ## Common Wrapping Patterns @@ -982,13 +941,7 @@ Q_INVOKABLE void initLogos(LogosAPI* api); // No override! Cannot load library calc_module_plugin.so: libcalc.so: cannot open shared object file ``` -**Fix:** Ensure `libcalc.so` / `libcalc.dylib` is in the same directory as the plugin. The build system should set RPATH to `$ORIGIN` (Linux) / `@loader_path` (macOS) so the plugin looks for libraries in its own directory. - -**macOS note:** As of writing, the RPATH may not be correctly set by logos-module-builder on macOS. As a workaround, set the library path before running: - -```bash -export DYLD_LIBRARY_PATH=result/lib/ -``` +**Fix:** Ensure `libcalc.so` / `libcalc.dylib` is in the same directory as the plugin. The build system sets RPATH to `$ORIGIN` (Linux) / `@loader_path` (macOS) so the plugin looks for libraries in its own directory. ### `initLogos` stores API pointer in wrong variable