diff --git a/logos-developer-guide.md b/logos-developer-guide.md index d819374..bffc691 100644 --- a/logos-developer-guide.md +++ b/logos-developer-guide.md @@ -233,6 +233,7 @@ The full set of available fields: | `view` | Yes (`ui_qml`) | -- | Relative path to the QML entry file (e.g. `Main.qml`). Required for `ui_qml` modules. | | `dependencies` | No | `[]` | Other Logos module names this depends on. Each entry must match the `name` field in that dependency's `metadata.json`. | | `interface_dependencies` | No | `[]` | Header *interfaces* this module binds at runtime, decoupled from any concrete module. Each entry is `{ name, file, impl_class?, input? }` — see [Dependency interfaces](#dependency-interfaces) and the [tutorial](tutorial-interface-dependencies.md). | +| `dependency_overrides` | No | `{}` | Per-dependency LIDL-contract source overrides, keyed by dependency name → `{ file, input?, impl_class? }`. Forces where a dependency's interface is read from; normally auto-resolved from the dep's `lidl` output. See [§9.2 Module Dependencies](#92-module-dependencies). | | `include` | No | `[]` | Additional files (e.g. shared libraries like `libwaku.so`, `libwaku.dylib`) to bundle alongside the plugin in the output. | | `nix.packages.build` | No | `[]` | Nix packages for build time | | `nix.packages.runtime` | No | `[]` | Nix packages for runtime | @@ -1103,6 +1104,27 @@ Each entry in `dependencies` must match the `name` field in that module's own `m 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. +#### How dependencies are consumed — the LIDL contract + +Each module publishes a small, language-neutral **LIDL interface contract** as a cheap flake output (`packages..lidl`), generated from its source with no plugin compile. When you depend on a module, the builder generates the typed `modules().` wrapper **from that published LIDL** — so building (or packaging) your module **does not build the dependency module**. The only step that still builds and bundles dependency plugins is the standalone-app run (`nix run` / `#run`), which has to, because it loads them. + +This is the same `logos-cpp-generator` from [§8.2](#82-the-c-sdk-code-generator), just driven by the dependency's LIDL contract — the same kind of `.lidl`/`.h` contract `interface_dependencies` uses — instead of inspecting a compiled plugin. Inspecting a compiled plugin (as §8.2 describes) is the manual/standalone path; for declared module dependencies the builder uses the contract path, which is why no dependency plugin is built. + +Because the contract is LIDL, the dependency's implementation language doesn't matter: the pipeline is `source → LIDL → C++` for a C++ module today, and `Rust → LIDL → C++` for a Rust module tomorrow — the same generated `modules().` wrapper either way. + +> **Transitional fallback.** A dependency built by an older `logos-module-builder` won't expose a `lidl` output yet; for those the builder falls back to the previous behavior (build the dependency and copy its generated headers), so mixed dependency graphs keep working. + +To force a specific contract source for a dependency — a committed `.lidl`, a header in another repo, etc. — add a `dependency_overrides` entry keyed by the dependency name: + +```json +"dependencies": ["calc_module"], +"dependency_overrides": { + "calc_module": { "file": "interfaces/calc.lidl" } +} +``` + +Each override is `{ file, input?, impl_class? }`: `file` is the `.lidl`/`.h` path (relative to this repo, or to the flake `input` if given), and `impl_class` is required for a `.h` file. Most modules never need this — auto-resolution from the dependency's `lidl` output is the default. + ### 9.3 Exposing Prometheus Metrics Infra operators monitor logos.dev nodes with Prometheus. The diff --git a/outputs/tutorial-composing-modules.md b/outputs/tutorial-composing-modules.md index de9c000..2084b3b 100644 --- a/outputs/tutorial-composing-modules.md +++ b/outputs/tutorial-composing-modules.md @@ -58,7 +58,7 @@ Three small config files declare the module, its dependency on `calc_module`, an ### 2.1 `metadata.json` — declare the dependency -The one field that matters here is `dependencies`: listing `calc_module` tells the builder to fetch `calc_module`'s headers and event metadata and generate a typed wrapper for it. The dependency name **must match** `calc_module`'s own `metadata.json` `name`. +The one field that matters here is `dependencies`: listing `calc_module` tells the builder to read `calc_module`'s published LIDL interface contract and generate a typed wrapper for it — without building `calc_module` itself. The dependency name **must match** `calc_module`'s own `metadata.json` `name`. ```json { @@ -427,7 +427,7 @@ nix flake update --override-input calc_module path:../logos-calc-module git add flake.lock ``` -Now build the full package. For a universal module with a dependency, this is where `logos-cpp-generator` runs over both `src/calc_aggregator_impl.h` and `calc_module`'s exported interface, emitting the plugin glue **and** the typed `modules().calc_module` wrapper under `generated_code/`: +Now build the full package. For a universal module with a dependency, this is where `logos-cpp-generator` runs over both `src/calc_aggregator_impl.h` and `calc_module`'s published LIDL contract, emitting the plugin glue **and** the typed `modules().calc_module` wrapper under `generated_code/` — note `calc_module`'s own plugin is not built here, only its LIDL is read: ```bash nix build diff --git a/tests/tutorial-composing-modules.test.yaml b/tests/tutorial-composing-modules.test.yaml index d45d783..bbb2707 100644 --- a/tests/tutorial-composing-modules.test.yaml +++ b/tests/tutorial-composing-modules.test.yaml @@ -60,7 +60,7 @@ sections: steps: - title: "`metadata.json` — declare the dependency" text: | - The one field that matters here is `dependencies`: listing `calc_module` tells the builder to fetch `calc_module`'s headers and event metadata and generate a typed wrapper for it. The dependency name **must match** `calc_module`'s own `metadata.json` `name`. + The one field that matters here is `dependencies`: listing `calc_module` tells the builder to read `calc_module`'s published LIDL interface contract and generate a typed wrapper for it — without building `calc_module` itself. The dependency name **must match** `calc_module`'s own `metadata.json` `name`. file: path: metadata.json language: json @@ -425,7 +425,7 @@ sections: nix flake update --override-input calc_module path:../logos-calc-module - run: "git add flake.lock" post_text: | - Now build the full package. For a universal module with a dependency, this is where `logos-cpp-generator` runs over both `src/calc_aggregator_impl.h` and `calc_module`'s exported interface, emitting the plugin glue **and** the typed `modules().calc_module` wrapper under `generated_code/`: + Now build the full package. For a universal module with a dependency, this is where `logos-cpp-generator` runs over both `src/calc_aggregator_impl.h` and `calc_module`'s published LIDL contract, emitting the plugin glue **and** the typed `modules().calc_module` wrapper under `generated_code/` — note `calc_module`'s own plugin is not built here, only its LIDL is read: - run: "nix build" - title: "Check the output"