Skip to content

CMake Bindings

The CMake format generates CMakeLists.txt and CMakePresets.json files for building Rice C++ bindings. This is run as a second pass after generating the Rice binding source files.

Rice supports building extensions with either extconf.rb or CMake. While extconf.rb works for simple bindings, CMake is vastly superior for anything more complex — it provides better cross-platform support, dependency management, and build configuration.

Configuration

format: CMake
project: my_extension

include_dirs:
  - "${CMAKE_CURRENT_SOURCE_DIR}/../headers"

See configuration for details on all options.

Usage

Generate bindings in two passes:

# 1. Generate Rice C++ source files
ruby-bindgen rice-bindings.yaml

# 2. Generate CMake build files
ruby-bindgen cmake-bindings.yaml

Then build:

cd /path/to/output
cmake --preset linux-debug    # or msvc-debug, macos-debug, etc.
cmake --build build/linux-debug

Skipping Files

The CMake config supports a skip option to exclude specific *-rb.cpp files from the generated CMakeLists.txt. However, in most cases it's better to add skip patterns to your Rice/FFI config instead — that way the problematic files are never generated, and CMake won't find them to include. The CMake skip is useful as a quick fix when you have stale generated files on disk that you don't want to recompile.

Output

The CMake format scans the output directory for *-rb.cpp files and generates:

flowchart LR
    subgraph Input
        CF["cmake-bindings.yaml"]
        S1["*-rb.cpp"]
    end

    CF & S1 --> RB["ruby-bindgen"]

    subgraph "CMake Output"
        C1["CMakeLists.txt"]
        C2["CMakePresets.json"]
    end

    RB --> C1 & C2

Project Files (requires project)

When the project option is set, ruby-bindgen generates the root CMakeLists.txt and CMakePresets.json. When project is omitted, these files are not generated — only subdirectory CMakeLists.txt files are produced. This is useful when you want to create and manage the root project files yourself and only regenerate subdirectory files on subsequent runs.

Top Level

The top-level CMakeLists.txt is a complete project file that configures the entire build:

  • C++17 standard requirement
  • Rice fetched from GitHub via FetchContent
  • Ruby detection via find_package(Ruby)
  • Library target (SHARED on MSVC, MODULE elsewhere)
  • Extension output configuration (correct suffix, visibility settings)
  • Subdirectory includes and *-rb.cpp source file listing

For a well-documented example, see the BitmapPlusPlus-ruby CMakeLists.txt. For details on how Rice uses CMake, see the Rice CMake documentation.

The top-level directory also gets a CMakePresets.json with build presets for all major platforms. For an example, see the BitmapPlusPlus-ruby CMakePresets.json. For details, see the Rice CMakePresets.json documentation.

Preset Platform Compiler
linux-debug / linux-release Linux GCC/Clang
macos-debug / macos-release macOS Clang
msvc-debug / msvc-release Windows MSVC
mingw-debug / mingw-release Windows MinGW GCC
clang-windows-debug / clang-windows-release Windows clang-cl

All presets use Ninja as the build generator and include appropriate compiler flags for each platform (visibility settings, debug info, optimization levels).

Subdirectories

Each subdirectory containing *-rb.cpp files gets a minimal CMakeLists.txt that lists its source files and any nested subdirectories:

# Subdirectories
add_subdirectory("hal")

# Sources
target_sources(${CMAKE_PROJECT_NAME} PUBLIC
  "matrix-rb.cpp"
  "image-rb.cpp"
)