From d27927aba51ae5cf351c81993a19e69da355a79b Mon Sep 17 00:00:00 2001 From: Dario Gabriel Lipicar Date: Tue, 18 Aug 2026 09:26:43 -0300 Subject: [PATCH] docs(generator): stop pointing callers at a flag that no longer exists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --backend qt is deleted from logos-qt-generator, and this repo was still signposting it. main.cpp's refusal said "Use it for --backend qt", and the usage text advertised --lidl … --backend qt and --from-header … --backend qt. Those now point at nothing — the exact failure the deletion removes, one repo over. The refusal names the real replacement chain instead: --backend cdylib here, then logos-qt-host-generator --backend cdylib for Qt-plugin packaging. docs/project.md's "Provider Generation" section documented three emitters that no longer exist; rewritten to state the seam and the two-step pipeline. docs/spec.md's dataflow diagram showed _qt_glue.h / _dispatch.cpp as outputs; the diagram is corrected and the sections describing that shape are marked historical rather than deleted, because the onInit wiring they document still applies to the cdylib glue. Co-Authored-By: Claude Opus 5 --- cpp-generator/docs/project.md | 39 ++++++++++++++++++++--------------- cpp-generator/docs/spec.md | 16 +++++++++----- cpp-generator/main.cpp | 19 +++++++++-------- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/cpp-generator/docs/project.md b/cpp-generator/docs/project.md index 9cda6a8..16b95ee 100644 --- a/cpp-generator/docs/project.md +++ b/cpp-generator/docs/project.md @@ -177,16 +177,24 @@ Flag plumbing: 2. `LogosModule.cmake` reads `${LOGOS_API_STYLE}` (default `qt`) and forwards `--api-style=${LOGOS_API_STYLE}` to the `logos-cpp-generator --general-only` invocation that writes the umbrella. Each module's Nix build emits **two** header derivations (`.headers-qt` and `.headers-lp`) via `buildHeaders.nix` — one `logos-cpp-generator --api-style=…` run per style, at the dep's build time. A consumer's `buildPlugin.nix` picks `dep.headers-${apiStyle}` and copies its `include/` straight into the build sandbox; no codegen runs at consume time. Nix's laziness means only the variant a downstream actually depends on is realised. 3. `parseApiStyleFlag()` in `generator_lib` parses `--api-style` once (rejecting the retired `std`); `main.cpp`'s `runUmbrellaMode` threads the resulting `ApiStyle` into `makeUmbrella*FromDeps`, and `legacy/main.cpp` threads it through `generateFromPlugin` / `writeUmbrellaHeader` (the QPluginLoader path). No per-style filenames are ever emitted; each module gets a single `_api.h` + `_api.cpp` pair regardless of style. -### Provider Generation (logos-qt-generator) +### Provider Generation — REMOVED -> The Qt provider glue (`lidl_gen_provider.{h,cpp}`) is emitted by **logos-qt-sdk's `logos-qt-generator`**, not this binary — it consumes the same `logos-lidl` frontend (+ the shared `lidl_emit_common` / `impl_header_parser` / `lidl_compat.h` / `metadata_dependencies.h` helpers, distributed under `share/lidl-frontend`). Documented here for reference. Adding a header to what `impl_header_parser.cpp` includes means adding it to that install list too (`nix/bin.nix`) — the qt-generator compiles that source out of the installed directory, so a header left behind breaks its build, not ours. - -- `lidlMakeProviderHeader(ModuleDecl, implClass, implHeader)` — generates Qt glue header - - Emits `nlohmannToQVariant()` helper when any method has `jsonReturn = true` - - Always emits an `onInit(LogosAPI*) override` that, via SFINAE'd helpers in `logos_module_context.h`, (a) copies the three runtime-injected properties (`modulePath`, `instanceId`, `instancePersistencePath`) into the impl, (b) constructs a per-module `LogosModules` aggregate and threads its pointer through the same base, and (c) installs the typed-event callback (`maybeSetEmitEvent`) consumed by `_events.cpp` method bodies. Impls that don't inherit `LogosModuleContext` compile unchanged — the helper overloads collapse to no-ops. The full `LogosAPI` is never exposed past the provider boundary. - - Always emits `#include "logos_sdk.h"` and a `std::unique_ptr m_logosModules` member; ownership lives on the provider, the context base sees only a non-owning `void*` reinterpreted in `LogosModuleContext::modules()` (which depends on the impl's TU having included `logos_sdk.h`). -- `lidlMakeProviderDispatch(ModuleDecl)` — generates callMethod/getMethods dispatch. `getMethods()` emits the full interface: each method tagged `type: "method"`, then each `module.events` entry tagged `type: "event"` (name, signature, parameters, escaped `description`; no returnType/isInvokable). There is no separate `getEvents()` — folding events into `getMethods()` keeps the provider vtable ABI-stable. -- `lidlMakeEventsSource(ModuleDecl, implClass, implHeader)` — generates `_events.cpp`: Qt-MOC-style method bodies for prototypes declared in the impl's `logos_events:` block. Each body marshals typed args into a `QVariantList` and calls `this->emitEventImpl_("", &args)` on the LogosModuleContext base. +> The Qt provider glue emitter (`lidl_gen_provider.{h,cpp}` in logos-qt-sdk) is **deleted**. It +> wrapped a plain impl directly in a Qt provider object, skipping the language-neutral seam. +> +> A module is a plain shared library. Turning one into a Qt plugin is a downstream HOSTING step, +> and the two halves meet only at `logos_module_impl.h`: +> +> ``` +> plain std impl +> --> logos-cpp-generator --backend cdylib -> logos_module_* C ABI exports +> --> logos-qt-host-generator --backend cdylib -> CdylibProvider : LogosProviderBase +> (logos-plugin-qt) +> ``` +> +> That seam is what lets the Rust and JS providers target the same ABI. `logos-qt-generator` still +> owns `--backend consumer` (Qt-typed dependency wrappers) and `--backend ui` (view plugins); +> `--backend qt` is refused with a message naming the replacement. ### Impl Header Parser (`impl_header_parser.h/cpp`) @@ -204,22 +212,19 @@ Flag plumbing: ```bash logos-cpp-generator --from-header src/my_module_impl.h \ - --backend qt \ - --impl-class MyModuleImpl \ - --impl-header my_module_impl.h \ + --backend cdylib \ --metadata metadata.json \ --output-dir ./generated_code ``` -Generates: `my_module_qt_glue.h`, `my_module_dispatch.cpp` +Generates the module-impl C ABI exports. Qt-plugin packaging is a separate step +(`logos-qt-host-generator --backend cdylib`). -### From LIDL file — provider glue +### From LIDL file — cdylib glue ```bash logos-cpp-generator --lidl my_module.lidl \ - --backend qt \ - --impl-class MyModuleImpl \ - --impl-header my_module_impl.h \ + --backend cdylib \ --output-dir ./generated_code ``` diff --git a/cpp-generator/docs/spec.md b/cpp-generator/docs/spec.md index ca2c232..ab4a9c6 100644 --- a/cpp-generator/docs/spec.md +++ b/cpp-generator/docs/spec.md @@ -40,11 +40,11 @@ Path 1: LIDL file Path 2: C++ impl header ▼ ▼ ModuleDecl ◄────── same AST ──────► ModuleDecl │ │ - ├──► lidlMakeProviderHeader() ◄──────┤ - │ → _qt_glue.h │ - │ │ - ├──► lidlMakeProviderDispatch() ◄─────┤ - │ → _dispatch.cpp │ + ├──► lidlMakeCdylibGlue*() │ + │ → logos_module_* C ABI │ + │ (Qt packaging is a │ + │ downstream step: │ + │ logos-qt-host-generator) │ │ │ ├──► lidlMakeHeader() │ │ → _api.h │ @@ -282,6 +282,12 @@ Module metadata (name, version, description, dependencies) still comes from `met ### Generated Output +> **Historical.** `_qt_glue.h` / `_dispatch.cpp` were emitted by +> `lidl_gen_provider`, which is deleted. A module now emits the `logos_module_*` C ABI +> (`--backend cdylib`) and `logos-qt-host-generator` turns that into a Qt plugin. The sections +> below describe the retired shape and are kept because the `onInit` wiring they document still +> applies to the cdylib glue. + #### Provider Glue (`_qt_glue.h`) Contains two classes: diff --git a/cpp-generator/main.cpp b/cpp-generator/main.cpp index 404b688..2f9cd62 100644 --- a/cpp-generator/main.cpp +++ b/cpp-generator/main.cpp @@ -633,14 +633,16 @@ int main(int argc, char* argv[]) } if (backend == "qt") { - err << "Error: Qt glue generation moved to logos-qt-generator " - "(logos-qt-sdk). Use it for --backend qt; this tool " - "keeps the Qt-free outputs (--header-to-lidl emits the " - ".lidl sidecar).\n"; + err << "Error: --backend qt was removed. A module is a plain " + "shared library: emit the module-impl C ABI with " + "--backend cdylib, then turn that into a Qt plugin with " + "logos-qt-host-generator --backend cdylib (logos-plugin-qt). " + "This tool keeps the Qt-free outputs (--header-to-lidl " + "emits the .lidl sidecar).\n"; return 6; } - err << "Error: --from-header supports --backend cdylib (Qt glue: logos-qt-generator)\n"; + err << "Error: --from-header supports --backend cdylib (Qt plugin packaging: logos-qt-host-generator)\n"; return 1; } @@ -650,16 +652,15 @@ int main(int argc, char* argv[]) err << "Usage: " << QFileInfo(app.applicationFilePath()).fileName() << " --lidl /path/to/module.lidl [--output-dir /path] [--module-only]\n" << " " << QFileInfo(app.applicationFilePath()).fileName() - << " --lidl /path/to/module.lidl --backend qt --impl-class Class --impl-header header.h [--output-dir /path]\n" - << " " << QFileInfo(app.applicationFilePath()).fileName() << " --lidl /path/to/module.lidl --backend cdylib [--output-dir /path] (glue-only: C exports come from the module's own language backend)\n" << " " << QFileInfo(app.applicationFilePath()).fileName() - << " --from-header src/impl.h --backend qt --impl-class Class --metadata metadata.json [--output-dir /path]\n"; + << " --from-header src/impl.h --backend cdylib --metadata metadata.json [--output-dir /path]\n"; return 1; } QString lidlPath = args.at(lidlIdx + 1); - // Provider glue mode: --backend qt --impl-class X --impl-header Y + // Backend dispatch. `qt` is refused above: a module is a plain shared + // library, and Qt-plugin packaging is logos-qt-host-generator's job. const int backendIdx = args.indexOf("--backend"); if (backendIdx != -1) { if (backendIdx + 1 >= args.size()) {