DimOS message generation and CDR
A standalone .msg generator and CDR toolkit for Python, C++ and Rust. It does
not depend on the DimOS runtime, a ROS installation, or a running robot.
The package is named dimos-cdrgen (import dimos_cdrgen). The current release is available on PyPI.
Documentation
The documentation source includes installation, Python, C++, and Rust quickstarts, dependency reuse, and CLI/API references. To build and preview the MkDocs site locally, follow the docs maintenance guide. The site build uses its own locked environment and does not install this package. The publishing guide covers local distribution validation, the default GitHub dry-run, and approval of registry ownership and OIDC setup.
Install the tool
From this package directory, prepare the pinned upstream parser and build local
artifacts. The preparation environment needs requests; the build environment
needs build, setuptools 77 or newer, and wheel.
python dimos_cdrgen/prepare_parser.py
python -m build --no-isolation
python -m pip install dist/dimos_cdrgen-0.1.0-py3-none-any.whl
The wheel and source archive contain the unchanged, hash-verified ROSIDL parser
and its license. Installing either artifact does not download upstream source.
A checkout with no prepared parser fails with an explicit preparation error.
Use --offline with a populated cache, or --archive /path/to/rosidl.tar.gz.
Normal Python dependencies must also be available for an offline installation.
Define and generate a message
In a separate directory, create interfaces/example_msgs/msg/Reading.msg:
int32 sequence
float64 value
Create pyproject.toml:
[project]
name = "acme"
version = "0.1.0"
[tool.dimos.messages]
source = "interfaces"
dimos-cdrgen
python -m pip install build/message-source/python
Generation reads the configuration and writes the following artifacts. It does not invoke a compiler or install a system toolchain.
Path under build/message-source |
Artifact |
|---|---|
python/ |
Installable Python project, type stubs and schema provider. |
cpp/ |
CMake projects and owned .msg sources for upstream ROSIDL/FastRTPS. |
rust/ |
Cargo crate, .msg sources and a ros2msg build.rs. |
schemas/, schemas.json |
Complete schema closure, including dependency messages. |
message-package.json |
Ownership, exact dependency versions, hashes and ABI. |
Python
from acme.example_msgs.msg import Reading
from dimos_cdrgen.registry import encode, decode
message = Reading(sequence=1, value=21.5)
assert decode(encode(message), Reading).value == 21.5
Runtime values and codecs use rosbags. Python wheels need no native compiler; there is no pybind extension. Import initializes the type registry without writing generated files or compiling code. Numeric arrays use NumPy.
C++
Install the tool's native extra and supply CMake plus a C/C++ compiler.
Prepare the generated package explicitly; pinned upstream dependencies are
fetched and verified here, not during Python import or installation.
from pathlib import Path
from dimos_cdrgen.native_build import prepare_cpp, write_cmake_toolchain
prefix = prepare_cpp(Path("build/message-source"))
write_cmake_toolchain(prefix, Path("build/acme-toolchain.cmake"))
For an application containing main.cpp, use:
cmake_minimum_required(VERSION 3.20)
project(reader LANGUAGES CXX)
find_package(acme CONFIG REQUIRED)
add_executable(reader main.cpp)
target_compile_features(reader PRIVATE cxx_std_17)
target_link_libraries(reader PRIVATE acme::messages)
#include <example_msgs/msg/reading.hpp>
#include <dimos_cdrgen/cdr.hpp>
int main() {
example_msgs::msg::Reading message;
message.sequence = 1;
message.value = 21.5;
auto wire = dimos::cdr::cdr_encode(message);
auto decoded = dimos::cdr::cdr_decode<example_msgs::msg::Reading>(wire);
return decoded.value == 21.5 ? 0 : 1;
}
cmake -S . -B build/app -DCMAKE_TOOLCHAIN_FILE="$PWD/build/acme-toolchain.cmake"
cmake --build build/app
./build/app/reader
The prefix contains generated headers, shared libraries and CMake exports.
The CDR helper is supplied by this library, with no DimOS SDK include path.
For offline preparation, use prepare_cpp(..., offline=True) with a populated
verified source/build cache. macOS also requires Apple's SDK and command-line tools.
Rust
In a Cargo application next to build/, declare:
[workspace]
exclude = ["build/message-source/rust"]
[dependencies]
acme-messages = { path = "build/message-source/rust" }
# Pin the upstream string-allocation fix until it is released.
cdr = { version = "=0.2.4", git = "https://github.com/TomCC7/cdr-rs", rev = "38a4368255d408faf374726653b39d4a4e9735cb" }
use acme_messages::example_msgs::msg::reading::Reading;
fn main() {
let message = Reading { sequence: 1, value: 21.5 };
let wire = cdr::serialize::<_, _, cdr::CdrLe>(&message, cdr::Infinite).unwrap();
let decoded: Reading = cdr::deserialize(&wire).unwrap();
assert_eq!(decoded.value, 21.5);
}
cargo run invokes ros2msg through the generated build.rs, writes declarations
into Cargo's OUT_DIR, and compiles the crate into the application. Use
cargo run --offline with cached dependencies. This does not create a Python
extension or publish a crate.
Dependency ownership and DimOS integration
Standard ROS message definitions are a separate catalog, not bundled here.
Set python-module when generated types belong inside an existing Python
package. Keep module as the CMake/Cargo identity:
[tool.dimos.messages]
module = "robot_messages"
python-module = "robot.messages"
This generates from robot.messages.example_msgs.msg import Reading while
retaining native package names derived from robot_messages. The Python
distribution name comes from [project].name. A consuming source project uses
"robot.messages" = "0.1.0" in its message dependency table and declares the
owning distribution in its Python build/runtime dependencies. Schemas and
provider metadata use robot.messages_schemas, so provider discovery does not
import the generated value modules recursively. Nested namespaces require
dimos-cdrgen==0.1.2 or later in build and runtime dependencies.
Declare an installed message package in tool.dimos.messages.dependencies with
its exact module/version. The generator imports its Python types, links its C++
declarations, and reuses its Rust crate types. It rejects conflicting ownership,
versions and schema hashes. The full schema closure remains available for MCAP
schema registration by consumers; this library itself does not record MCAP.
The DimOS dimos-build-config adapter from PR #4461 calls this library's
package_settings() to support pip install . and editable projects alongside
blueprint declarations. Existing setuptools callers can use setup_arguments().
Both call the same prepare() implementation as dimos-cdrgen.
Neither requires copying the generator into a DimOS application. Reinstall an
editable message project and restart Python processes after changing .msg files.
The codec provides schema/CDR interoperability. It does not implement a ROS 2 node, DDS discovery, topic QoS, or live ROS 2 network interoperability. Unsupported bounds and declared-default semantics remain explicit in the generated manifest and the known limitations.
Run tests from this package alone
python -m pip install '.[test,native]'
PYTHONPATH=. python -m dimos_cdrgen.prepare_test_inputs
PYTHONPATH=. python -m pytest dimos_cdrgen
# Explicit compiled Python/C++/Rust exchange (requires native toolchains):
PYTHONPATH=. DIMOS_NATIVE_ACCEPTANCE=1 python -m pytest dimos_cdrgen/test_native_consumer.py
Test preparation downloads only pinned public upstream test schemas. Use
--offline --cache /path/to/verified/archives to reuse archives. Native acceptance
can use DIMOS_OFFLINE=1, DIMOS_NATIVE_TEST_CACHE, and DIMOS_NATIVE_SOURCE_DIRS
(a JSON map of upstream project names to prepared source directories). Isolated
installation tests require DIMOS_MESSAGE_WHEELHOUSE containing the Python build
and runtime dependency wheels. The optional joint DimOS adapter test also needs
DIMOS_BUILD_CONFIG_SOURCE; it is not required to use the standalone library.
Prepare and publish a release
Use the publishing guide for the locked build environment,
standalone consumer checks, and manual dry-run, testpypi, or pypi workflow.
The default dry-run never uploads. A real upload requires an approved registry
account and project, Trusted Publisher configuration, and a matching version tag.
- Confirm the authorized registry account and publishing destination. Choose a new version; registry uploads cannot replace an existing release.
- Prepare the pinned parser, then build the wheel and sdist in a clean directory. Retain upstream licenses and source hashes. Do not commit prepared upstream code.
- Run
python -m twine check dist/*, install the wheel in a clean environment, rebuild from the sdist offline, and run the language/dependency acceptance tests. - Choose the supported Python/platform matrix and verify those targets before declaring release support. Linux checks alone do not validate macOS.
- Only after approval of the account and destination, use the registry's authorized publishing flow. No upload command is part of build or install.
C++ prefixes and generated Rust crates are separate native build artifacts. Publishing the Python tool does not publish a standard-message catalog or Cargo packages. Packaged Rust dependencies use exact versions and need normal Cargo resolution (local patches/workspaces or separately published dependency crates).
Metadata
Release files for dimos-cdrgen 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| dimos_cdrgen-0.1.2.tar.gz | 77.7 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dimos_cdrgen-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 148.9 kB
Release files / dimos_cdrgen-0.1.2.tar.gz
| Download URL | dimos_cdrgen-0.1.2.tar.gz |
|---|---|
| Size | 77.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5a767df0364fc32bccc286b48f204317ec8278d04fc9b9ee6a3d7fb9653b7ebf
|
|
BLAKE2b-256 checksum How to use checksums |
880aad00b03760da952948ad0a0782d49b6d0f2f465f6f2b59b865994155180c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / dimos_cdrgen-0.1.2-py3-none-any.whl
| Download URL | dimos_cdrgen-0.1.2-py3-none-any.whl |
|---|---|
| Size | 71.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9857c8cc40de58b03f94cb81e7d27ae3caac98101c96cdaa2965413a332e685f
|
|
BLAKE2b-256 checksum How to use checksums |
299fa4fe6f8ea4dcafd3001c868ebbc751bb0af83aecb1fe6523765c12cdedba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for dimos-cdrgen 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for dimos_cdrgen-0.1.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.