Skip to main content
The execution event SDK is made up of two packages, called monad-event-ring and monad-exec-events. These are described in more detail in the Rust API guide, but for now it’s enough to just know their names. In the future, Category Labs may publish these packages to crates.io, but that is not how the SDK is currently distributed. Instead, the user’s Cargo.toml file declares the upstream source of these dependencies to be a particular release tag of the git repository where the SDK source code is located. Dependencies which are sourced from git rather than crates.io are explained in this section of the Cargo Book.

Where is the Rust SDK source code?

The execution event Rust SDK lives in same source code repository as the execution daemon (here). Most of the code in this repository in written in either C or C++, the languages used by the execution daemon itself. The repository also contains a few Rust wrapper APIs, one of which is the Rust execution events SDK. The top-level Cargo.toml file for all the Rust components is located in the rust/ subdirectory. Many of the functions in the execution events C SDK are reused by Rust, via an FFI interface. The main way this affects you as a Rust user is that you must ensure that a recent enough C compiler is selected when Cargo calls CMake and bindgen from the SDK’s build.rs build scripts. The C SDK uses some recent C23 language features, and requires either gcc-13 or clang-19. If you run cc -v and it reports an older compiler, you will need to set the CC environment variable to tell CMake to select a newer compiler.

Building the example program

Step 1: install prerequisite development packages

You might already have some of these installed, but make sure you have at least the minimum required version (newer versions will probably work, but are not explicitly tested). In addition to a Rust toolchain, you will need:
RequirementUbuntu package nameMinimum versionWhat is it used for?
C compilergcc-13 or clang-19see package namesThe core event library (libmonad_event.a) is written in C, and is used by the Rust library
C++ compilerg++-13 or clang-19see package namesThe optional C++ components are not used by Rust, but the CMake configure step will report an error if it cannot find a C++ compiler
CMakecmakeCMake 3.23libmonad_event.a is built with CMake, via build.rs integration with cargo
zstd librarylibzstd-devanySnapshot event ring files are compressed with zstd; this library is needed to decompress them
libhugetlbfslibhugetlbfs-devanylibhugetlbfs is used to locate the default hugetlbfs mount point that holds event ring shared memory files
libclangclang-19clang-19Rust’s bindgen requires the a recent version of the libclang library
We will also need git and curl.

macOS compatiblity

Real-time data requires a Linux host (because the execution daemon itself does), but you can compile and run the example program on historical data using macOS. This allows you to “try before you buy” and explore the SDK before going through the trouble of setting up a Monad node on Linux. In this case, you do not need libhugetlbfs (which is a Linux-only library), but you will need a recent XCode toolchain, the libzstd compression library, and CMake. The last two are not included in the default XCode development tools, so you’ll probably want to use Homebrew or MacPorts to install these onto your system. As for XCode itself, any version since 16.3 should work, but it has only been tested with version 23.2 (the real requirement is for Apple Clang 17).1

Dependencies quickstart

To install all of the dependenices in one shot on Ubuntu 24.04 or higher, run this command (feel free to use more recent verions, e.g., clang-20):
$ sudo apt install git curl gcc g++ cmake clang-19 libzstd-dev libhugetlbfs-dev
Even if you compile libmonad_event.a with gcc, the Rust bindgen utility still uses the libclang tool to programmatically generate Rust bindings to C code. Technically you should not need the full clang compiler, just the libclang package, but some users have reported trouble without installing it.The reason you need version 19 (or greater) is that clang-19 was the first version to support enough features from the C23 language standard to be able to compile the SDK. If you see errors that imply that bindgen cannot understand the constexpr keyword, then bindgen has automatically selected a libclang version that is too old.If you have multiple libclang versions on the system (the default clang is version 18 on Ubuntu 24.04), installing a newer version may not help, if the underlying problem is that bindgen is selecting the wrong one by default. Later on in this guide (during the cargo build step) we’ll explain more about how to fix some common problems with libclang version selection.

Step 2: create a new package and copy the example code into it

First, create a new cargo package for the example program:
$ cargo new --bin event-sdk-example-rust
$ cd event-sdk-example-rust
Next, we’ll overwrite the default “Hello world” main.rs source file with the example program code, downloaded from github:
$ curl https://raw.githubusercontent.com/category-labs/monad/refs/tags/release/exec-events-sdk-v1.1/rust/crates/monad-exec-events/examples/eventwatch.rs > src/main.rs

Step 3: integrating with the SDK packages

Create the following Cargo.toml file:
[package]
name = "event-sdk-example-rust"
version = "0.1.0"
edition = "2021"

[dependencies]
chrono = "0.4.34"
clap = { version = "4.2", features = ["derive"] }
lazy_static = "1.5.0"

[dependencies.monad-event-ring]
git = "https://github.com/category-labs/monad"
tag = "release/exec-events-sdk-v1.1"

[dependencies.monad-exec-events]
git = "https://github.com/category-labs/monad"
tag = "release/exec-events-sdk-v1.1"

Step 4: build the project

cargo build
The first time you build will be very slow, because it will fetch the monad repository and all transitive git submodules. None of them are needed for the SDK, but cargo checks them out and there is currently no way to override this (see this issue). Thankfully, the git cache is usually shared by all Cargo projects (in $HOME/.cargo/git) so this long download should only happen a single time, not once per project. You may need to tell CMake to use a more recent C compiler than the default one it detects, which you can do using the CC environment variable. The example below uses the bash terse syntax for setting environment variables in the scope of the next command to be run:
CC=clang-19 cargo build
If you encounter any build errors, check out the “trouble-shooting” section after this one. Otherwise, the build should produce a working executable file. Try running it with the -h flag to print the help:
cargo run -- -h
If all was successful, continue on to the next step in the guide.

Trouble-shooting common build errors

libclang errors

The most common source of errors when building is when bindgen selects an outdated libclang version, as explained earlier. This typically appears as either:
  • An error explicitly mentioning libclang OR
  • A message that includes the text “Unable to generate bindings”
Setting the environment variable CC=clang-19 only influences the compiler that CMake uses to build the C SDK library, libmonad_event.a. Namely, it does not the affect the libclang version that is used by bindgen to generate the bindings. CC specifies a particular binary program, whereas libclang is a shared library that is dynamically loaded by a build.rs build script. They are (for the most part) not affected by the same environment variables. There are a number of environment variables that control the behavior of how libclang is located and configured, and they’re documented in the “Environment Variables” section of the Rust libclang bindings library. Some advice we have found works well:
  • Setting LLVM_CONFIG_PATH to point to the full path to the llvm-config binary is the best option; this command bakes in a lot of details about how LLVM was built and installed on the system, to make it easier for users of LLVM (such as bindgen) to find the configuration they need
  • In some unusual cases, you may select the right libclang but it may be configured strangely, so that it cannot find the basic libc header files anymore (typical symptoms are claims that stddef.h, assert.h, or string.h are missing); you can can figure out the location of these files on the system and pass them as system include directories (the -isystem clang option) to libclang through bindgen using the BINDGEN_EXTRA_CLANG_ARGS environment variable; on macOS this looks like:
    BINDGEN_EXTRA_CLANG_ARGS="-isystem $(xcrun --show-sdk-path)/usr/include"
    
    and in a typical Linux setup it looks like this:
    BINDGEN_EXTRA_CLANG_ARGS="-isystem /usr/include"
    

zstd library errors

A common error with MacPorts on macOS is the inability of the C compiler to find the zstd.h header file, or the inability of the linker to find the libzstd library. This is because the system C compiler will not search in the /opt/local directory hierarchy by default. To fix this, export the CFLAGS and RUSTFLAGS environment variables as follows:
export CFLAGS=-I/opt/local/include
export RUSTFLAGS=-L/opt/local/lib
Alternatively, you can set CC to a MacPorts-provided C compiler, which will know to search there.

Footnotes

  1. “Apple Clang” is based on, but different than, vanilla LLVM Clang. Apple Clang 17 is based on LLVM/Clang 19, thus the discrepancy in the requirements table.