ZeroDDS IDL Compiler

zerodds-idlc reads OMG IDL 4.2. It checks, lints and formats IDL files, prints the model, and generates source for one of 21 target languages: the data types and their codecs. The sub-command dlrl writes DDS 1.2 §8 DLRL object and home classes.

Install

cargo install zerodds-idlc --version 1.0.0-rc.7

Pre-built binaries are published through the package managers (Linux .deb/.rpm, macOS .pkg, Windows MSI/Scoop, multi-arch Docker). In the Linux packages the binary is part of zerodds-cli.

Quickstart

zerodds-idlc check schemas/sensor.idl
zerodds-idlc generate --lang rust --out gen/rust schemas/sensor.idl

The sub-command comes first; there is no form without one. generate writes one file per input file into --out, named after the input (here gen/rust/sensor.rs). Java and Ada write fixed names instead (ZdTypes.java, ZdCodec.java; zd_types.ads). #include, #define and #ifdef in the IDL file are expanded by the built-in preprocessor. The command line has no -D; a build.rs defines macros with zerodds_build::Config::define.

Sub-commands

  • check — parse and lower; report every diagnostic.
  • lint — the rules a valid file can still break.
  • format — the canonical form, to stdout by default. --check names each non-canonical file and exits 1, --write rewrites it in place.
  • dump-ast — the model, as a tree.
  • print-deps — the types each declaration names.
  • generate — one language's source for the model.
  • dlrl — DDS 1.2 §8 DLRL object and home classes, from the three DLRL pragmas.

Languages

--lang is required for generate and dlrl. generate takes one of 21 languages, or all for every one of them in one run:

rust, c++, c, java, c#, python, typescript, go, ocaml, ada, d,
elixir, julia, lua, nim, swift, zig, node, ada83, f#, kotlin

cpp/cxx, csharp/cs, fsharp/fs and ts are accepted besides. An unknown name lists the valid ones. dlrl takes c++, c#, java, typescript or all.

zerodds-idlc generate --lang c++ --out gen/cpp sensor.idl
zerodds-idlc generate --lang 'c#' --out gen/cs sensor.idl

For an IDL interface, --lang rust writes a DDS-RPC 1.0 binding with request and reply types, codec, client and dispatcher. Fifteen further languages write the interface's declarations without a codec. c, python and node have no mapping for an interface and refuse a model that declares one (exit 1). --rpc-mapping selects the DDS-RPC service mapping. zerodds-idlc has no CORBA option; see zerodds-corba-codegen for CORBA stubs and skeletons.

Options

  • --out <DIR> — generate/dlrl: where the files go. Default: the current directory.
  • -I, --include <DIR> — where a quoted #include is searched after the including file's own directory; repeatable, in the order given.
  • --default-extensibility final|appendable|mutable — what an aggregate whose source names no extensibility is taken to be. Default: the specification's appendable; an annotation in the source still wins. Cyclone DDS's idlc takes such an aggregate as final; for IDL written for Cyclone, pass --default-extensibility final.
  • --encoding <ENC> — generate: xcdr1, xcdr2 (default), pl-cdr1, pl-cdr2, delimited-cdr.
  • --endian le|be — generate: the byte order the codec is planned for. Default: le. It does not change the emitted text; the preamble names it. --xcdr-endianness BE|LE is the DDS-TS 1.0 spelling.
  • --dialect <NAME> — generate: reproduce one peer's answers to every wire axis at once. Default: specification; further cyclone, rti, fastdds, opendds, opensplice, ros-fastrtps, ros-cyclone, omniorb, tao, jacorb. --<axis> <VALUE> overrides one answer, after --dialect and in the order given. The axes and their values are listed in the man page and in docs/wire-axis-flags.md.
  • Mappings of generate: --cpp-mapping psm|native|classic (default psm), --java-mapping psm|omg (default psm), --rust-map entries|btree-map (default entries), --rpc-mapping basic|enhanced|enhanced-empty (default basic).
  • Build contract of generate/dlrl: --stamp <FILE> is written last and only when the run succeeded; --depfile <FILE> is a Make dependency file listing every IDL file read; --output-manifest <FILE> is JSON of the files read and written.
  • Diagnostics: --strict (OMG IDL 4.2 only, every vendor extension rejected), --ros2 (ROS 2 dialect, unqualified member types like Pose pose;), --json (machine-readable diagnostics), --deny-warnings (exit non-zero when anything was reported).

Vendor key pragmas (#pragma keylist, DCPS_DATA_KEY) are applied as @key.

Exit codes

  • 0 — nothing to report.
  • 1 — a diagnostic was reported, or --check found a file to reformat.
  • 2 — the command line was wrong.
  • 3 — a file could not be read.

Build integration

In a Cargo build.rs, zerodds-build runs the same pipeline as a library call. It reports every IDL file it read, included ones too, to Cargo and needs no zerodds-idlc on the PATH.

[build-dependencies]
zerodds-build = "1.0.0-rc.7"
// build.rs
fn main() -> Result<(), zerodds_build::Error> {
    zerodds_build::Config::new()
        .include_dir("idl")
        .compile(&["idl/Robot.idl"])
}

In CMake, zerodds_idlc_generate() from zeroddsConfig.cmake runs zerodds-idlc generate with --stamp and --depfile.

Reference

Stability

CLI surface stable for 1.0.x. Additions are minor bumps; flag removals require a major bump.

Runnable example

ZeroDDS IDL-Compiler

zerodds-idlc liest OMG IDL 4.2. Er prüft, lintet und formatiert IDL-Dateien, gibt das Modell aus und erzeugt Quellcode für eine von 21 Zielsprachen: die Datentypen und ihre Codecs. Der Unterbefehl dlrl schreibt DLRL-Objekt- und Home-Klassen nach DDS 1.2 §8.

Installation

cargo install zerodds-idlc --version 1.0.0-rc.7

Vorgefertigte Binaries werden über die Paketmanager veröffentlicht (Linux .deb/.rpm, macOS .pkg, Windows MSI/Scoop, Multi-Arch-Docker). In den Linux-Paketen gehört das Binary zu zerodds-cli.

Quickstart

zerodds-idlc check schemas/sensor.idl
zerodds-idlc generate --lang rust --out gen/rust schemas/sensor.idl

Der Unterbefehl steht an erster Stelle; eine Form ohne Unterbefehl gibt es nicht. generate schreibt je Eingabedatei eine Datei nach --out, benannt nach der Eingabe (hier gen/rust/sensor.rs). Java und Ada schreiben stattdessen feste Namen (ZdTypes.java, ZdCodec.java; zd_types.ads). #include, #define und #ifdef in der IDL-Datei expandiert der eingebaute Präprozessor. Die Kommandozeile hat kein -D; ein build.rs definiert Makros mit zerodds_build::Config::define.

Unterbefehle

  • check — parsen und lowern; jede Diagnose melden.
  • lint — die Regeln, die eine gültige Datei trotzdem verletzen kann.
  • format — die kanonische Form, standardmäßig auf stdout. --check nennt jede nicht kanonische Datei und endet mit 1, --write schreibt sie an Ort und Stelle um.
  • dump-ast — das Modell als Baum.
  • print-deps — die Typen, die jede Deklaration nennt.
  • generate — der Quellcode einer Sprache für das Modell.
  • dlrl — DLRL-Objekt- und Home-Klassen nach DDS 1.2 §8, aus den drei DLRL-Pragmas.

Sprachen

--lang ist bei generate und dlrl Pflicht. generate nimmt eine von 21 Sprachen oder all für alle in einem Lauf:

rust, c++, c, java, c#, python, typescript, go, ocaml, ada, d,
elixir, julia, lua, nim, swift, zig, node, ada83, f#, kotlin

Daneben werden cpp/cxx, csharp/cs, fsharp/fs und ts angenommen. Ein unbekannter Name listet die gültigen auf. dlrl nimmt c++, c#, java, typescript oder all.

zerodds-idlc generate --lang c++ --out gen/cpp sensor.idl
zerodds-idlc generate --lang 'c#' --out gen/cs sensor.idl

Für ein IDL-interface schreibt --lang rust eine DDS-RPC-1.0-Bindung mit Request- und Reply-Typen, Codec, Client und Dispatcher. Fünfzehn weitere Sprachen schreiben die Deklarationen des Interfaces ohne Codec. c, python und node haben keine Abbildung für ein Interface und weisen ein Modell ab, das eines deklariert (Exit-Code 1). --rpc-mapping wählt die Dienst-Abbildung von DDS-RPC. zerodds-idlc hat keine CORBA-Option; CORBA-Stubs und -Skeletons siehe zerodds-corba-codegen.

Optionen

  • --out <DIR> — generate/dlrl: wohin die Dateien geschrieben werden. Standard: das aktuelle Verzeichnis.
  • -I, --include <DIR> — wo ein #include in Anführungszeichen nach dem Verzeichnis der einbindenden Datei gesucht wird; mehrfach angebbar, in der angegebenen Reihenfolge.
  • --default-extensibility final|appendable|mutable — als was ein Aggregat gilt, dessen Quelle keine Extensibility nennt. Standard: appendable wie in der Spezifikation; eine Annotation in der Quelle hat Vorrang. Das idlc von Cyclone DDS nimmt ein solches Aggregat als final; für IDL, die für Cyclone geschrieben ist, --default-extensibility final angeben.
  • --encoding <ENC> — generate: xcdr1, xcdr2 (Standard), pl-cdr1, pl-cdr2, delimited-cdr.
  • --endian le|be — generate: die Byte-Reihenfolge, für die der Codec geplant wird. Standard: le. Sie ändert den erzeugten Text nicht; die Präambel nennt sie. --xcdr-endianness BE|LE ist die Schreibweise aus DDS-TS 1.0.
  • --dialect <NAME> — generate: die Antworten eines Gegenübers auf alle Wire-Achsen auf einmal übernehmen. Standard: specification; außerdem cyclone, rti, fastdds, opendds, opensplice, ros-fastrtps, ros-cyclone, omniorb, tao, jacorb. --<axis> <VALUE> überschreibt eine Antwort, nach --dialect und in der angegebenen Reihenfolge. Die Achsen und ihre Werte stehen in der Man-Page und in docs/wire-axis-flags.md.
  • Abbildungen von generate: --cpp-mapping psm|native|classic (Standard psm), --java-mapping psm|omg (Standard psm), --rust-map entries|btree-map (Standard entries), --rpc-mapping basic|enhanced|enhanced-empty (Standard basic).
  • Build-Vertrag von generate/dlrl: --stamp <FILE> wird zuletzt geschrieben und nur, wenn der Lauf gelungen ist; --depfile <FILE> ist eine Make-Abhängigkeitsdatei mit jeder gelesenen IDL-Datei; --output-manifest <FILE> ist JSON mit den gelesenen und geschriebenen Dateien.
  • Diagnosen: --strict (nur OMG IDL 4.2, jede Vendor-Erweiterung wird abgewiesen), --ros2 (ROS-2-Dialekt, unqualifizierte Member-Typen wie Pose pose;), --json (maschinenlesbare Diagnosen), --deny-warnings (Exit-Code ungleich 0, sobald etwas gemeldet wurde).

Vendor-Key-Pragmas (#pragma keylist, DCPS_DATA_KEY) werden als @key angewendet.

Exit-Codes

  • 0 — nichts zu melden.
  • 1 — eine Diagnose wurde gemeldet, oder --check hat eine Datei gefunden, die neu formatiert werden muss.
  • 2 — die Kommandozeile war falsch.
  • 3 — eine Datei konnte nicht gelesen werden.

Build-Integration

In einem Cargo-build.rs führt zerodds-build dieselbe Pipeline als Bibliotheksaufruf aus. Es meldet Cargo jede gelesene IDL-Datei, auch die eingebundenen, und braucht kein zerodds-idlc im PATH.

[build-dependencies]
zerodds-build = "1.0.0-rc.7"
// build.rs
fn main() -> Result<(), zerodds_build::Error> {
    zerodds_build::Config::new()
        .include_dir("idl")
        .compile(&["idl/Robot.idl"])
}

In CMake ruft zerodds_idlc_generate() aus zeroddsConfig.cmake zerodds-idlc generate mit --stamp und --depfile auf.

Referenz

Stabilität

CLI-Oberfläche stabil für 1.0.x. Ergänzungen sind Minor-Bumps; Flag-Entfernungen erfordern einen Major-Bump.

Lauffähiges Beispiel