docs: LIDL-based dependency consumption + dependency_overrides (#65)

* docs: document LIDL-based dependency consumption + dependency_overrides

Tutorial-sync for "concrete dependencies via LIDL":
- Developer guide §9.2: explain that each module publishes a cheap LIDL
  interface contract (packages.<sys>.lidl) and that consuming a dependency
  generates modules().<dep> from that LIDL WITHOUT building the dependency's
  plugin — only the standalone-app run (#run) bundles/builds deps. Notes the
  cross-language pipeline (Rust -> LIDL -> C++) and the transitional fallback
  for deps that don't yet expose a `lidl` output.
- Document the new `dependency_overrides` metadata field (§9.2 + field table).
- Composing Modules tutorial: correct the prose that said the builder "fetches
  calc_module's headers" — it now reads calc_module's published LIDL contract
  and does not build calc_module's plugin at the aggregator build step.

Depends on logos-cpp-sdk#77, logos-plugin-qt#9, logos-module-builder#110 (the
described behavior ships with those).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* address review: regenerate composing tutorial md; reconcile §8.2/§9.2

- Regenerate outputs/tutorial-composing-modules.md so the committed markdown
  matches the updated YAML prose (it had stale "fetch headers" / "exported
  interface" wording). Verified identical to `doctest generate`.
- Developer guide §9.2: add a note tying the LIDL-contract dependency wrapper
  generation to §8.2 — it's the same logos-cpp-generator driven by the dep's
  LIDL/.h contract (like interface_dependencies) rather than inspecting a
  compiled plugin (the manual/standalone path), so the two sections no longer
  read as conflicting mechanisms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dario Lipicar
2026-06-08 12:22:30 -03:00
committed by GitHub
co-authored by Claude Opus 4.7
parent c9f47391e5
commit c2cd6f09eb
3 changed files with 26 additions and 4 deletions
+22
View File
@@ -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.<system>.lidl`), generated from its source with no plugin compile. When you depend on a module, the builder generates the typed `modules().<dep>` 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().<dep>` 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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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"