Skip to content

feat: consume concrete deps via LIDL (no dep plugin build) + publish lidl output#110

Merged
dlipicar merged 3 commits into
masterfrom
feat/deps-via-lidl
Jun 8, 2026
Merged

feat: consume concrete deps via LIDL (no dep plugin build) + publish lidl output#110
dlipicar merged 3 commits into
masterfrom
feat/deps-via-lidl

Conversation

@dlipicar

@dlipicar dlipicar commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Consume concrete dependencies via LIDL — no dep plugin build

The core of the feature: building (and packaging) a module no longer builds its universal dependency modules. Each module publishes a cheap LIDL contract; consumers generate the typed modules().<dep> bindings from it. The only thing that still builds/bundles dep plugins is the standalone app run (apps.default / #run), which must — it loads them.

// unchanged consumer code — modules().<dep> still works, just no dep build
modules().calc_module.add(3, 5);
modules().calc_module.onVersionReady([](const std::string& v){ ... });

This PR

  • mkLogosModule.nix — new packages.<sys>.lidl output: a cheap runCommand that runs logos-cpp-generator --header-to-lidl over the universal impl header (no Qt/plugin compile). Per-dependency classification: a dep exposing a lidl output (or a dependency_overrides entry) is LIDL-based → threaded to the backend as staticDeps (generated via --dep, no dep plugin build); otherwise it takes the TRANSITIONAL header-copy fallback (legacyHeaderDepNames), identical to today.
  • parseMetadata.nixdependencies normalized to name strings (accepts object entries); new optional dependency_overrides ({ file, input?, impl_class? }) to force a dep's LIDL/header source.
  • buildCppPlugin.nix — same classification + staticDeps threading for QML C++-backend (UI) modules.

The header-copy fallback is isolated and banner-commented (# TRANSITIONAL … Remove once all modules expose packages.<sys>.lidl) so it can be deleted as a localized change once modules migrate.

Cross-repo chain (merge order)

  1. feat: LIDL interface IR — --header-to-lidl frontend + --dep backend logos-cpp-sdk#77--header-to-lidl + --dep
  2. feat: pass concrete deps to the generator as --dep (LIDL, no dep build) logos-plugin-qt#9 — pass --dep flags
  3. logos-module-builder ← this PR

Verification (all with --auto-local)

  • No dep plugin build: building the mixed consumer test_context_module_cpp, the universal dep test_basic_module_cpp's closure contains only …-lidl.drvno -module-lib/-headers-std; the legacy dep test_basic_module builds via the fallback (as intended).
  • lidl output is cheap: no module-plugin compile in its build closure (just the generator).
  • Runtime: the integration suite passes 168/1/25 — including test_context_module_cpp's cross-module calls and the typed event round-trip (subscribeToBasicCppEventstriggerTestEventgetLastTestEventData) through the LIDL-generated wrapper. (The 1 failure is a pre-existing flaky SIGSEGV in test_ipc_new_api_module → test_extlib_module, a legacy/fallback path untouched by this change.)
  • ws test logos-module-builder --auto-local passes (incl. test-parse-metadata, QML + framework integration).

🤖 Generated with Claude Code

Building/packaging a module no longer builds its (universal) dependency
modules — only `#run` (the standalone app) still bundles dep plugins.

- mkLogosModule: new packages.<sys>.lidl output — a cheap codegen-only
  derivation that runs `logos-cpp-generator --header-to-lidl` over the universal
  impl header (no Qt/plugin compile), publishing the module's interface LIDL.
- mkLogosModule: per-dependency classification. A dep that exposes a `lidl`
  output (or has a dependency_overrides entry) is LIDL-based → passed to the
  backend as `staticDeps` (generated via --dep, no dep plugin build). Deps
  without a `lidl` output take the TRANSITIONAL header-copy fallback
  (`legacyHeaderDepNames` → resolvedModuleDeps), identical to today; isolated
  and banner-commented for removal once all modules publish LIDL.
- parseMetadata: normalize `dependencies` to name strings (accept object
  entries) and add optional `dependency_overrides` ({ file, input?, impl_class? })
  to force a specific LIDL/header source per dep.
- buildCppPlugin (QML C++ backend): same classification + staticDeps threading,
  so UI modules also stop building their universal deps.

Requires logos-cpp-sdk#77 (--header-to-lidl / --dep) and logos-plugin-qt#9
(staticDeps → --dep). A follow-up flake.lock bump pins those once merged
(mirrors the interface-deps plugin-core bump, #109); local builds use
`ws ... --auto-local`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 6, 2026 22:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the module build pipeline so that building a module no longer builds/bundles its universal concrete dependency modules. Instead, dependencies can be consumed via a cheap published LIDL contract (packages.<sys>.lidl), and consumers generate typed modules().<dep> bindings from that contract; only standalone app runs still build/bundle dependency plugins.

Changes:

  • Normalize metadata.json concrete dependencies to a list of name strings, and add optional dependency_overrides to force a dependency’s LIDL/header source.
  • Classify concrete deps into LIDL-based (staticDeps → passed as --dep inputs to codegen, no dep plugin build) vs TRANSITIONAL header-copy fallback (legacyHeaderDepNames → builds deps, same as today).
  • Publish a new per-module lidl package output for universal modules by running logos-cpp-generator --header-to-lidl on the universal impl header.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
lib/parseMetadata.nix Normalizes dependencies entries and introduces dependency_overrides parsing/validation.
lib/mkLogosModule.nix Implements concrete-dep classification, threads staticDeps, and publishes a lidl package output.
lib/buildCppPlugin.nix Mirrors the same dep classification for QML C++ backend builds and threads staticDeps into backend builds.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/mkLogosModule.nix Outdated
Comment thread lib/buildCppPlugin.nix Outdated
Comment thread lib/parseMetadata.nix
…a tests

- depLidlOf now explicitly guards `packages`/`<system>` so a raw-derivation
  dependency input returns null (→ transitional header-copy fallback) rather
  than risking a throw. Applied in mkLogosModule.nix and buildCppPlugin.nix.
- test-parse-metadata.nix: cover `dependencies` object-entry normalization and
  `dependency_overrides` parsing/validation (file required; .h needs impl_class).

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

dlipicar commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the Copilot review (commit 971be95):

  • depLidlOf (in both mkLogosModule.nix and buildCppPlugin.nix) now explicitly guards packages/<system> and returns null for a non-flake / raw-derivation dependency input, so it falls through to the transitional header-copy path instead of risking a throw. (The previous x.packages.<sys>.lidl or null already short-circuits missing intermediate attrs in Nix, but the explicit guard makes the intent unambiguous.)
  • Added tests/test-parse-metadata.nix coverage for the new behavior: dependencies object-entry normalization, and dependency_overrides parsing/validation (file required; .h requires impl_class). 70 assertions pass.

🤖 Generated with Claude Code

… backends

Pin the merged --header-to-lidl/--dep generator (logos-cpp-sdk#77) and the
staticDeps-aware Qt backend (logos-plugin-qt#9) so this module builder's LIDL
dependency consumption works against published inputs (not just --auto-local).

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

dlipicar commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Bumped the flake inputs now that the upstream PRs are merged (commit 1360c78):

So this PR now consumes the published backends (no --auto-local needed). Verified the merged sources contain the feature, and the builder's pure-eval test suite passes against the bumped lock (nix build .#checks.<sys>.default → 243 tests). CI here builds the integration checks against the pinned merged deps.

🤖 Generated with Claude Code

@dlipicar dlipicar merged commit 598ca36 into master Jun 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants