辻斬り Generic C++ Bindings Generator
Project description
tsujikiri — 辻斬り
Cut through C++ bindings
tsujikiri parses C++ headers via libclang, filters by namespace and pattern, transforms symbols — rename, remap types, inject code — then renders ready-to-compile bindings through a Jinja2 template. Precise control, zero boilerplate.
Built-in support for LuaBridge3 (Lua bindings), LuaLS (Lua Language Server annotations), pybind11 (Python bindings), and Python type stubs (.pyi). Custom formats are first-class.
How It Works
C++ Header (.hpp)
│
▼ libclang
Intermediate Representation (IR)
│
├─▶ FilterEngine suppress classes / methods / fields by pattern
│
├─▶ Transform Pipeline rename, inject, remap types
│
▼ Jinja2 templates
Target Binding Code
Each phase is independently configurable per input file and per output format.
Documentation
Full documentation is available at tsujikiri.readthedocs.io.
Installation
Using pip:
pip install tsujikiri
Using uv:
uv pip install tsujikiri
Requirements: Python ≥ 3.12
Quick Start
1. Write an input config
# myproject.input.yml
source:
path: myproject.hpp
parse_args: ["-std=c++17"]
include_paths: ["/usr/local/include"]
filters:
namespaces: ["myproject"]
classes:
whitelist: ["Vec3", "Matrix4", "Camera"]
constructors:
include: true
generation:
includes: ["<myproject.hpp>"]
2. Generate bindings
# Print to stdout
tsujikiri -i myproject.input.yml --target luabridge3 -
# Write to file
tsujikiri -i myproject.input.yml --target luabridge3 bindings.cpp
# Generate multiple outputs in one pass
tsujikiri -i myproject.input.yml \
--target luabridge3 bindings.cpp \
--target pybind11 py_bindings.cpp \
--target pyi mymodule.pyi
# Dry-run: parse and filter, print summary
tsujikiri -i myproject.input.yml --target luabridge3 - --dry-run
# List available formats
tsujikiri --list-formats
3. Example output (LuaBridge3)
Given a header with a Vec3 class, tsujikiri emits:
#include <myproject.hpp>
#include <LuaBridge/LuaBridge.h>
void register_myproject(lua_State* L)
{
luabridge::getGlobalNamespace(L)
.beginClass<myproject::Vec3>("Vec3")
.addConstructor<void(*)(float, float, float)>()
.addFunction("length", &myproject::Vec3::length)
.addFunction("dot", &myproject::Vec3::dot)
.addProperty("x", &myproject::Vec3::x)
.addProperty("y", &myproject::Vec3::y)
.addProperty("z", &myproject::Vec3::z)
.endClass();
}
Built-in Formats
luabridge3
Generates C++ registration code for LuaBridge3.
tsujikiri -i project.input.yml --target luabridge3 bindings/lua_bindings.cpp
Handles: classes, constructors, instance/static methods, overloaded methods, properties, enums, free functions, inheritance.
luals
Generates Lua Language Server annotation stubs.
tsujikiri -i project.input.yml --target luals types/myproject.lua
Emits ---@class, ---@field, ---@param, ---@return annotations with C++→Lua type mappings.
pybind11
Generates C++ registration code for pybind11.
tsujikiri -i project.input.yml --target pybind11 src/py_bindings.cpp
Handles: classes with multiple inheritance, constructors, instance/static methods, overloaded methods (via py::overload_cast), read-write/read-only properties, enums (via py::enum_), free functions, doc strings.
pyi
Generates Python type stub files (.pyi) for use alongside pybind11 bindings.
tsujikiri -i project.input.yml --target pyi mymodule.pyi
Emits Python-typed stubs with @overload, @staticmethod, class inheritance, enum stubs as class Foo(int), and C++→Python type mappings.
Custom Formats
Create a myformat.output.yml alongside your templates:
format_name: "myformat"
format_version: "1.0"
description: "My custom binding format"
type_mappings:
"std::string": "String"
"int32_t": "int"
unsupported_types:
- "CFStringRef"
template:
{%- block prologue -%}
# DO NOT EDIT - Auto-generated Python stubs for {{ module_name }} by tsujikiri
from __future__ import annotations
from typing import overload
{{ code_injections | code_at("beginning") }}
{%- endblock %}
# ... finish the template
Point tsujikiri at your format directory:
tsujikiri -i project.input.yml --target myformat out/bindings.cpp -f ./my_formats/
CLI Reference
tsujikiri [OPTIONS]
Options:
-i, --input FILE Input config YAML (required)
-t, --target FORMAT FILE Output target: FORMAT is a built-in name or path to
.output.yml; FILE is the output path ('-' for stdout).
Repeatable for multiple simultaneous outputs.
-c, --classname CLASS Generate bindings for a single class only
-f, --formats-dir DIR Extra directory to search for .output.yml files (repeatable)
--list-formats Print available formats and exit
--dry-run Parse and filter only; print IR summary without generating
-m, --manifest-file FILE Write API manifest JSON to FILE; compare if FILE exists
--check-compat Exit 1 if manifest shows breaking API changes
--embed-version Embed the API version hash in the generated code
--trace-transforms Print transform stages and their targets to stderr
--dump-ir [FILE] Dump the post-transform IR as JSON (default: stdout)
--validate-config Validate input config (regex patterns, stage names) and exit
-h, --help Show this message and exit
Development
# Install task runner and sync dependencies
pip install just uv
just sync
# Run tests
just test
# Run tests with coverage
just coverage
# Build wheel
just build
The test suite covers parsing, filtering, transforms, generation, CLI integration, and end-to-end compilation with LuaBridge3.
Coverage
License
MIT — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tsujikiri-0.9.0.tar.gz.
File metadata
- Download URL: tsujikiri-0.9.0.tar.gz
- Upload date:
- Size: 65.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa3f56d6867a4fee9a0bb8fc67ca72a98de2f0c6450f6b6a17fae2c1d847c475
|
|
| MD5 |
9c1cbbfcfbee62a75e91bab3f8be787a
|
|
| BLAKE2b-256 |
6360b67e220c6ed0a7e6027b45fb86f3b0d3a838fa2c65b2b9715577c4d051a9
|
Provenance
The following attestation bundles were made for tsujikiri-0.9.0.tar.gz:
Publisher:
release.yml on kunitoki/tsujikiri
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tsujikiri-0.9.0.tar.gz -
Subject digest:
fa3f56d6867a4fee9a0bb8fc67ca72a98de2f0c6450f6b6a17fae2c1d847c475 - Sigstore transparency entry: 1308508670
- Sigstore integration time:
-
Permalink:
kunitoki/tsujikiri@992c4a05413e503f7fa9d126d1761091471682f9 -
Branch / Tag:
refs/tags/v0.9.0 - Owner: https://github.com/kunitoki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@992c4a05413e503f7fa9d126d1761091471682f9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tsujikiri-0.9.0-py3-none-any.whl.
File metadata
- Download URL: tsujikiri-0.9.0-py3-none-any.whl
- Upload date:
- Size: 74.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fb6bfb1fcaf3271e77c1e0e10b8caf67f7c9c98294388359d5b3160035b1205
|
|
| MD5 |
80f1028cd8671f659cf2204a595b8d17
|
|
| BLAKE2b-256 |
740cf099f77ad10cc73df2c7878ef7d5832b30352bf51059367439f79a6f50b8
|
Provenance
The following attestation bundles were made for tsujikiri-0.9.0-py3-none-any.whl:
Publisher:
release.yml on kunitoki/tsujikiri
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tsujikiri-0.9.0-py3-none-any.whl -
Subject digest:
1fb6bfb1fcaf3271e77c1e0e10b8caf67f7c9c98294388359d5b3160035b1205 - Sigstore transparency entry: 1308508751
- Sigstore integration time:
-
Permalink:
kunitoki/tsujikiri@992c4a05413e503f7fa9d126d1761091471682f9 -
Branch / Tag:
refs/tags/v0.9.0 - Owner: https://github.com/kunitoki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@992c4a05413e503f7fa9d126d1761091471682f9 -
Trigger Event:
push
-
Statement type: