# How to Build bpftime from Source: A Complete CMake Guide

> Learn how to build bpftime from source using CMake. Follow our guide to clone the repo, install dependencies like libelf and LLVM, and configure your build for custom settings or use the convenient Makefile.

- Repository: [eunomia-bpf/bpftime](https://github.com/eunomia-bpf/bpftime)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Building bpftime from source requires cloning the repository with submodules, installing system dependencies (libelf, boost, LLVM), and using either the wrapper `Makefile` for convenience or direct CMake invocation for custom configurations.**

The `bpftime` project from `eunomia-bpf/bpftime` provides a userspace eBPF runtime with LLVM JIT and uBPF backends. Whether you need the full runtime with uprobes or just the standalone VM for embedding, this guide covers the complete build process using the CMake-based build system defined in the repository's root [`CMakeLists.txt`](https://github.com/eunomia-bpf/bpftime/blob/main/CMakeLists.txt) and `cmake/StandardSettings.cmake`.

## Prerequisites and Dependencies

Before you build bpftime from source, ensure your system meets the build-time requirements.

### System Requirements

The build process requires a Linux environment (Ubuntu 23.04 is the primary development target) with CMake, a C++ compiler, and several system libraries. The [`installation.md`](https://github.com/eunomia-bpf/bpftime/blob/main/installation.md) file in the repository specifies that you need development headers for ELF parsing, compression, and YAML configuration.

### Installing Dependencies on Ubuntu

Install the required packages using `apt-get`:

```bash
sudo apt-get update && sudo apt-get install \
    libelf1 libelf-dev zlib1g-dev make cmake git \
    libboost-all-dev binutils-dev libyaml-cpp-dev \
    ca-certificates clang llvm pkg-config llvm-dev

```

For GPU acceleration support, install the CUDA toolkit and set the `BPFTIME_CUDA_ROOT` environment variable to your CUDA installation prefix before running CMake.

## Cloning the Repository with Submodules

The bpftime project vendors dependencies like Catch2, spdlog, argparse, and libbpf as Git submodules. You must clone recursively to obtain these:

```bash
git clone --recurse-submodules https://github.com/eunomia-bpf/bpftime.git
cd bpftime

```

If you cloned without `--recurse-submodules`, initialize them manually:

```bash
git submodule update --init --recursive

```

## Build Methods

The repository provides two primary ways to build bpftime from source: a convenience `Makefile` wrapper or direct CMake invocation.

### Using the Wrapper Makefile (Recommended)

The root `Makefile` provides pre-configured targets that invoke CMake with sensible defaults. This is the fastest way to build bpftime from source.

**Debug build with all components and unit tests:**

```bash
make build

```

This creates a Debug build in the `build/` directory with all runtime components, agents, and unit tests enabled.

**Release build (production ready):**

```bash
make release

```

The `release` target builds in Release mode, creates static libraries (`libbpftime.a`), and installs the CLI tools to `~/.bpftime`. Add this directory to your `PATH`:

```bash
export PATH=$PATH:~/.bpftime

```

**Build only the eBPF VM:**

For embedding the VM without the full runtime or uprobe capabilities:

```bash
make build-vm    # Simple JIT backend

make build-llvm  # LLVM JIT backend

```

The `Makefile` forwards these commands to CMake with flags defined in `cmake/StandardSettings.cmake`, setting options like `BPFTIME_LLVM_JIT` or `BPFTIME_ENABLE_UNIT_TESTING` appropriately.

### Direct CMake Invocation

For custom configurations, invoke CMake directly. This method gives you full control over the build options defined in `cmake/StandardSettings.cmake`.

```bash
cmake -Bbuild -DCMAKE_BUILD_TYPE=Release \
      -DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_INFO \
      -DBPFTIME_ENABLE_LTO=NO \
      -DBPFTIME_LLVM_JIT=YES
cmake --build build --config Release --target install -j$(nproc)
export PATH=$PATH:~/.bpftime

```

Key CMake flags for building bpftime from source include:

- `BPFTIME_ENABLE_UNIT_TESTING` – Build Catch2 unit-test targets
- `BPFTIME_ENABLE_LTO` – Enable link-time optimization
- `BPFTIME_LLVM_JIT` – Use the LLVM-based JIT/AOT compiler (recommended)
- `BPFTIME_UBPF_JIT` – Build the legacy uBPF JIT backend
- `BPFTIME_BUILD_WITH_LIBBPF=OFF` – Build without libbpf (useful for macOS)
- `BPFTIME_ENABLE_CUDA_ATTACH` – Enable CUDA/GPU attach support (requires `BPFTIME_CUDA_ROOT`)
- `BPFTIME_ENABLE_IOURING_EXT` – Build with io_uring helper extensions

## Custom Build Configurations

When you build bpftime from source, you can tailor the components to your specific use case.

### Enabling LLVM JIT

The LLVM JIT backend provides better optimization than the simple uBPF JIT. Enable it when building from source:

```bash
cmake -Bbuild -DBPFTIME_LLVM_JIT=YES ..

```

Or use the Makefile:

```bash
make build-llvm

```

### GPU and CUDA Support

To build bpftime with CUDA support for GPU-accelerated eBPF programs:

```bash
export BPFTIME_CUDA_ROOT=/usr/local/cuda-12.8
cmake -Bbuild -DBPFTIME_ENABLE_CUDA_ATTACH=1 ..

```

### Building Only the VM

If you only need the eBPF VM without the runtime agents or syscall interceptors, build from the `vm/` directory or use:

```bash
make build-vm

```

This produces a minimal library suitable for embedding in other projects, as documented in [`vm/README.md`](https://github.com/eunomia-bpf/bpftime/blob/main/vm/README.md).

## Verifying the Installation

After you build bpftime from source, verify the installation:

```bash
bpftime --version
bpftime --help

```

To run the unit test suite:

```bash
make build-unit-test
make unit-test

```

Or with CMake directly:

```bash
cmake --build build --target unit-test
./build/test/unit-test

```

## Summary

Building bpftime from source involves these key steps:

- **Clone recursively** with `git clone --recurse-submodules` to fetch vendored dependencies like Catch2 and libbpf
- **Install system dependencies** including libelf, boost, LLVM, and binutils development headers
- **Use the wrapper Makefile** for convenience (`make release` for production builds, `make build` for debug with tests)
- **Configure CMake flags** directly for custom builds, such as enabling `BPFTIME_LLVM_JIT` for the LLVM backend or `BPFTIME_ENABLE_CUDA_ATTACH` for GPU support
- **Verify** by running `bpftime --version` and the unit test suite

## Frequently Asked Questions

### What dependencies are required to build bpftime from source?

You need CMake, a C++ compiler, and development libraries for libelf, zlib, boost, binutils, and yaml-cpp. On Ubuntu, install these via `apt-get install libelf-dev zlib1g-dev libboost-all-dev binutils-dev libyaml-cpp-dev clang llvm llvm-dev`. Optional dependencies include the CUDA toolkit for GPU support.

### How do I enable the LLVM JIT backend when building bpftime?

Pass the `-DBPFTIME_LLVM_JIT=YES` flag to CMake, or use the convenience command `make build-llvm`. This enables the LLVM-based JIT/AOT compiler in `cmake/StandardSettings.cmake`, which provides better optimization than the legacy uBPF backend.

### Can I build bpftime without libbpf for macOS compatibility?

Yes. Set `-DBPFTIME_BUILD_WITH_LIBBPF=OFF` when invoking CMake. This disables components that depend on libbpf, allowing you to build the core VM and runtime on macOS or other systems without full Linux kernel headers.

### How do I run the unit tests after building bpftime?

Use the Makefile targets `make build-unit-test` followed by `make unit-test`, which compile and execute the Catch2 test suite. Alternatively, build with `-DBPFTIME_ENABLE_UNIT_TESTING=ON` and run `./build/test/unit-test` directly after compiling with CMake.