Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ However, these changes did require some breaking changes, which include:
* `Arg("").isBuffer()` is replaced by `ArgBuffer("")`
* `Function().noGVL()` is replaced by `NoGvL()`
* `is_convertible` methods must now return a `double` instead of a `Convertible` enum
* All function/method parameter default values are verified. You may see errors like "ArgumentError: Type is not registered with Rice" or "Invalid AnyCast". In either case, make sure to check that specified default values are correct.

## 4.7.1 (2025-10-28)
Updates:
Expand Down
46 changes: 46 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Rice Project Context

## Overview
Rice is a C++ header-only library for creating Ruby bindings. It provides:
- Simple C++ syntax for wrapping and defining Ruby classes
- Automatic type conversions between C++ and Ruby
- Automatic exception handling
- Smart pointer support for garbage collection

## Build & Test

### Windows (MSVC)
```bash
build_rice.bat # Build the project
build/msvc-debug/test/unittest.exe # Run tests
```

### CMake
```bash
cmake --preset msvc-debug # Configure
cmake --build build/msvc-debug # Build
```

## Project Structure
- `rice/` - Main header-only library source
- `rice/rice.hpp` - Combined header (generated)
- `rice/stl.hpp` - STL bindings header (generated)
- `test/` - Test suite
- `docs/` - Documentation (mkdocs)
- `examples/` - Usage examples

## Development Notes
- Requires C++17 or later
- Requires Ruby 2.7+
- Run `rake` to regenerate combined headers and run tests

## Conventions
-

## Current Work
- Ruby Kaigi 2026 talk submission (deadline: Jan 11, 2026 JST)
- Documents in `rubykaigi/`: abstract.md, pitch.md, review_committee.md
- Talk title: "Rice: A Journey from Pybind11 Envy to Wrapping OpenCV"

## Decisions Made
-
71 changes: 71 additions & 0 deletions docs/ecosystem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Ecosystem

Rice is part of a larger ecosystem of tools for wrapping C++ libraries for Ruby. Together, these tools provide a complete pipeline from C++ headers to documented, type-annotated Ruby gems.

## Toolchain

```mermaid
flowchart TD
subgraph Input
CPP[C++ Library<br/>headers + source]
end

subgraph Parsing
CLANG[Clang / ffi-clang<br/>parse C++ headers]
end

subgraph Generation
BINDGEN[ruby-bindgen<br/>generate Rice binding code]
end

subgraph Rice
WRAP[Type Conversion<br/>From_Ruby / To_Ruby]
INTROSPECT[Introspection<br/>Registry]
MEM[Memory Management<br/>prevent GC issues]
RBS[RBS Generation<br/>type signatures]
DOCS[Doc Generation<br/>Markdown]

INTROSPECT --> RBS
INTROSPECT --> DOCS
end

subgraph Build
CMAKE[CMake<br/>build extension]
end

subgraph Output
GEM[Ruby Gem<br/>compiled + docs + RBS types]
end

CPP --> CLANG
CLANG --> BINDGEN
BINDGEN --> Rice
Rice --> CMAKE
CMAKE --> GEM
```

What once took weeks of manual work can now be done in hours.

## Tools

### Clang / ffi-clang

[Clang](https://clang.llvm.org/) is a C/C++ compiler that provides libclang, a library for parsing C++ code. [ffi-clang](https://github.com/ffi/ffi-clang) provides Ruby bindings to libclang, allowing Ruby code to walk the C++ AST (Abstract Syntax Tree) and extract classes, methods, constructors, enums, and other declarations.

### ruby-bindgen

[ruby-bindgen](https://github.com/cfis/ruby-bindgen) uses ffi-clang to parse C++ headers and automatically generates Rice binding code. Point it at a library's headers and it produces correct binding code.

### Rice

Rice wraps C++ code and exposes it to Ruby. It also includes:

- **Introspection API** - Rice tracks every class, method, and attribute it wraps in an internal registry. This metadata is exposed to Ruby, enabling documentation and type generation. See [Registries](ruby_api/registries.md).

- **RBS Generation** - Generate [RBS](https://github.com/ruby/rbs) type signatures for wrapped classes, giving Ruby's type checkers full visibility into your C++ bindings. See [RBS](packaging/rbs.md).

- **API Documentation Generation** - Generate Ruby-style API documentation in Markdown format from wrapped classes. See [Documentation](packaging/documentation.md).

### CMake

[CMake](https://cmake.org/) is the de-facto C++ build system. Rice includes an improved FindRuby.cmake module with fixes that have been upstreamed to CMake itself, making native extension builds work reliably across platforms. See [CMake](packaging/cmake.md).
90 changes: 83 additions & 7 deletions docs/history.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,91 @@
# History

Rice originated as Excruby, a project to interface with C++-based trading software at Automated Trading Desk in Mount Pleasant, South Carolina. The Ruby bindings for Swig were at the time less mature than they are today, and did not suit the needs of the project.
Rice originated as Excruby, a project to interface with C++-based trading software at Automated Trading Desk in Mount Pleasant, South Carolina. The Ruby bindings for Swig at the time were not suitable for the needs of the project.

Excruby was written as a set of helper functions and classes for interfacing with the Ruby interpreter in an exception-safe manner. Over the course of five years, the project grew into wrappers for pieces of the Ruby API, but the original helper functions remained as part of the public interface.
Excruby started as a set of helper functions and classes for interfacing with the Ruby interpreter in an exception-safe manner. Over the course of five years, the project grew into wrappers for pieces of the Ruby API, but the original helper functions remained as part of the public interface.

This created confusion for the users of the library,because there were multiple ways of accomplishing most tasks -- directly through the C API, through a low-level wrapper around the C API and through a high-level abstraction of the lower-level interfaces.
This created confusion for the users of the library, because there were multiple ways of accomplishing most tasks -- directly through the C API, through a low-level wrapper around the C API and through a high-level abstraction of the lower-level interfaces.

Rice was then born in 2008 as an attempt to clean up the interface. Rice keeps the lower-level wrappers, but as an implementation detail; the public interface is truly a high-level abstraction around the Ruby C API.
Rice was born in 2008 as an attempt to clean up the interface. Since then Rice has continued to evolve. It has gone through several eras:

However, it was still difficult to use Rice to wrap C++ libraries. A major drawback was that Rice required its own compilation step to create is own library. At the time (and still today), there is not a standard way to install compiled C++ packages.
| Era | Versions | Theme |
|-----------|-----------|-------------------------------------------------------------|
| 2003-2008 | Excruby | Ruby API wrappers |
| 2008-2010 | 1.2-1.4 | Foundation, Ruby 1.9 |
| 2011-2014 | 1.4.3-1.6 | C++11, Ruby 2.x |
| 2015-2020 | 1.7-2.2 | Maintenance |
| 2021 | 3.0-4.0 | Header-only rewrite, C++17 |
| 2022-2024 | 4.0.x-4.3 | STL expansion |
| 2025 | 4.5-4.9 | OpenCV-driven evolution (buffers, pointers, overloads, etc) |

To address this, version 4, released in 2021, was a major rewrite that changed Rice into a header-only library. This made it much easier to use Rice to wrap C++ libraries. In addition, version 4 took full advantage of all the C++ template metaprogramming functionality in C++17 and higher to make it easier to create Ruby extensions for C++ libraries.
---

In 2025, Rice version 4.5 was released. Version 4.5 was based on learnings from wrapping the OpenCV library. OpenCV exposes a large C++ API that makes heavy use of C++ templates, overridden methods and constructors, C style callbacks and other C++ features. To successfully wrap the library required making numerous changes to Rice which are described in the [CHANGELOG.md](https://github.com/ruby-rice/rice/blob/master/CHANGELOG.md).
## 2008-2010: Foundation

Rice kept the lower-level wrappers, but as an implementation detail hidden behind C++ classes that provided a higher high-level abstraction around the Ruby C API.

| Version | Date | Major Features |
|--------------|----------|----------------------------------------------------|
| First commit | Jan 2008 | Rice development begins, evolved from Excruby |
| 1.2.0 | Oct 2009 | First tagged release |
| 1.4.0 | Aug 2010 | Ruby 1.9.2, constructor defaults, implicit casting |

---

## 2011-2014: Ruby 2.x and C++11

Rice kept pace with Ruby's evolution through the 2.x series and adopted C++11 features like unique_ptr.

| Version | Date | Major Features |
|---------|----------|----------------------------|
| 1.5.0 | May 2013 | Ruby 2.0 |
| 1.6.0 | Feb 2014 | Ruby 2.1, C++11 unique_ptr |

---

## 2015-2020: Maintenance

A quiet period of maintenance. Rice started to show its limitations - it was difficult to use Rice to wrap C++ libraries. A major drawback was that Rice required its own compilation step to create its own library. At the time (and still today), there is not a standard way to install compiled C++ packages.

| Version | Date | Major Features |
|---------|----------|-----------------------|
| 1.7.0 | Jan 2015 | Ruby 2.2 |
| 2.0.0 | Nov 2015 | Deprecated Ruby < 2.0 |
| 2.2.0 | Jan 2020 | Ruby 2.7 |

---

## 2021: Header-Only Rewrite

Version 4, released in 2021, was a major rewrite that changed Rice into a header-only library. This made it much easier to use Rice to wrap C++ libraries. In addition, version 4 took full advantage of C++ template metaprogramming functionality in C++17 and higher to make it easier to create Ruby extensions for C++ libraries.

| Version | Date | Major Features |
|---------|----------|-------------------------------------------------------------|
| 3.0 | Jan 2021 | C++14 minimum, GitHub Actions CI |
| 4.0 | Apr 2021 | Header-only, C++17, From_Ruby/To_Ruby redesign, STL support |

---

## 2022-2024: STL Expansion

With the header-only foundation in place, Rice expanded its STL support to cover more container types and use cases.

| Version | Date | Major Features |
|---------|----------|------------------------------------------------|
| 4.1.0 | Apr 2023 | std::map, std::variant, iterators, enumerators |
| 4.2.0 | Jan 2024 | Ruby 3.3, Buffer class |
| 4.3 | Feb 2024 | STL containers with pointers, std::string_view |

---

## 2025: OpenCV-Driven Evolution

In 2025, Rice underwent rapid evolution based on learnings from wrapping the OpenCV library. OpenCV exposes a large C++ API that makes heavy use of C++ templates, overloaded methods and constructors, C style callbacks and other C++ features. To successfully wrap the library required making numerous changes to Rice.

| Version | Date | Major Features |
|---------|----------|------------------------------------------------------------------|
| 4.5.0 | Feb 2025 | Method/constructor overloading, keyword args, callbacks, rvalues |
| 4.6.0 | Jun 2025 | Buffer rewrite, std::tuple/set/multimap, const-aware types |
| 4.7.0 | Oct 2025 | Introspection API, RBS generation, API doc generation |
| 4.8.0 | Dec 2025 | 2x faster compilation, 30% smaller binaries |
| 4.9.0 | Dec 2025 | Smart pointer redesign (Std::SharedPtr, Std::UniquePtr) |
4 changes: 3 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Introduction

Rice is a C++ 17 header-only library that serves dual purposes. First, it makes it much easier to create Ruby bindings for existing C++ libraries. Second, it provides an object oriented interface to Ruby's C API that makes it easy to embed Ruby and write Ruby extensions in C++.
Rice is a C++ 17 header-only library that serves dual purposes. First, it makes it much easier to create Ruby bindings for existing C++ libraries. Second, it provides an object-oriented interface to Ruby's C API that makes it easy to embed Ruby and write Ruby extensions in C++.

Rice is similar to [Boost.Python](https://github.com/boostorg/python) and [pybind11](https://github.com/pybind/pybind11) in that it minimizes boilerplate code needed to interface with C++. It does this by automatically determining type information allowing Ruby objects to be converted to C++ and vice versa.

Expand All @@ -12,6 +12,8 @@ Rice provides:
* Smart pointers for handling garbage collection
* A C++ API to wrap Ruby's C API

Rice is also part of a larger [ecosystem](ecosystem.md) of tools that together provide a complete pipeline from C++ headers to documented, type-annotated Ruby gems.

## Project Details

Source code is hosted on GitHub: <https://github.com/ruby-rice/rice>
Expand Down
7 changes: 6 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ theme:
markdown_extensions:
- admonition
- pymdownx.details
- pymdownx.superfences
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.inlinehilite
Expand All @@ -44,6 +48,7 @@ nav:
- index.md
- Installation: installation.md
- Why Rice?: why_rice.md
- Ecosystem: ecosystem.md
- Projects: projects.md
- History: history.md
- Migration: migration.md
Expand Down
Loading