#define MCAP_IMPLEMENTATION // Define this in exactly one .cpp file
#include <mcap/writer.hpp>
#include <chrono>
#include <cstring>
#include <iostream>
// Returns the system time in nanoseconds. std::chrono is used here, but any
// high resolution clock API (such as clock_gettime) can be used.
mcap::Timestamp now() {
return mcap::Timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count());
}
int main() {
// Initialize an MCAP writer with the "ros1" profile and write the file header
mcap::McapWriter writer;
auto status = writer.open("output.mcap", mcap::McapWriterOptions("ros1"));
if (!status.ok()) {
std::cerr << "Failed to open MCAP file for writing: " << status.message << "\n";
return 1;
}
// Register a Schema
mcap::Schema stdMsgsString("std_msgs/String", "ros1msg", "string data");
writer.addSchema(stdMsgsString);
// Register a Channel
mcap::Channel chatterPublisher("/chatter", "ros1", stdMsgsString.id);
writer.addChannel(chatterPublisher);
// Create a message payload. This would typically be done by your own
// serialization library. In this example, we manually create ROS1 binary data
std::array<std::byte, 4 + 13> payload;
const uint32_t length = 13;
std::memcpy(payload.data(), &length, 4);
std::memcpy(payload.data() + 4, "Hello, world!", 13);
// Write our message
mcap::Message msg;
msg.channelId = chatterPublisher.id;
msg.sequence = 1; // Optional
msg.logTime = now(); // Required nanosecond timestamp
msg.publishTime = msg.logTime; // Set to logTime if not available
msg.data = payload.data();
msg.dataSize = payload.size();
writer.write(msg);
// Finish writing the file
writer.close();
}
Run make
to build the library using a Docker container. This requires Docker
to be installed, and will produce Linux (ELF) binaries compiled in an Ubuntu
container with the clang compiler. If you want to build binaries for another
platform or using your own compiler, run make build-host
. This requires a
working C++ compiler toolchain and Conan to be installed.
Output binaries can be found in:
cpp/bench/build/Release/bin/
,cpp/examples/build/Release/bin/
cpp/test/build/Debug/bin/
.
The C++ implementation of MCAP is maintained as a header-only library with the following dependencies:
- lz4 (tested with lz4/1.9.3)
- zstd (tested with zstd/1.5.2)
If your project does not need lz4
or zstd
support, you can optionally disable these by defining
MCAP_COMPRESSION_NO_LZ4
or MCAP_COMPRESSION_NO_ZSTD
respectively.
To simplify installation of dependencies, the Conan package manager can be used with the included conanfile.py.
For using MCAP with CMake, the third-party olympus-robotics/mcap_builder repository provides a helpful wrapper.
If you use an alternative approach, such as CMake's FetchContent or directly vendoring the dependencies, make sure you use versions equal or greater than the versions listed above.
Refer to the API documentation in
mcap/mcap.hpp
for full details. The high-level interfaces for reading and writing are
McapReader
and McapWriter
.
- Update the
#define MCAP_LIBRARY_VERSION
and all other occurrences of the same version number, e.g. inconanfile.py
,build.sh
, and others. - Once the version number has been updated, create and push a git tag named
releases/cpp/vX.Y.Z
matching the new version number. - Make a pull request to conan-io/conan-center-index to update the mcap recipe:
- Update
config.yml
to add the new version. - Update
all/conandata.yml
to add an entry pointing at the tarball from the new release tag. - Follow the instructions for developing recipes locally to test the recipe.
- Examples of previous changes to the mcap recipe: https://github.com/conan-io/conan-center-index/commits/master/recipes/mcap
- Update
This project uses a semantic version number to notify users of changes to public APIs.
This semantic version can be read from types.hpp
, defined as MCAP_LIBRARY_VERSION
.
The public API includes names that can be included from the .hpp
files in include/mcap
, excluding anything namespaced under mcap::internal
.
This API version does not cover the compiled ABI of the library. Projects including mcap
are expected
to compile it from source as part of their build process.
Build rules in CMake or conanfile.py
files are not covered as part of this public API.