「cinrs」でRustにCを直書きしたら、build.rsが要らなくなった
- 公開
- 正式公開 2026-09-22(リポジトリ作成 2026-09-06)
- 作り手
- tanakh(個人)
- 対応
- Rust(crates.io)・Linux・Mac・Windows
- 価格
- 無料(Apache-2.0 / MIT のデュアルライセンス)
- 評価
- GitHub のスター 31(2026-10-05)
どんなアプリか
cinrs は、Rust のファイルの中に直接書いた C のソース(C89〜C23、GNU 拡張つき)を、クレートのコンパイル中に Rust へ変換し、C で定義したものを通常の Rust の項目として使えるようにする手続き的マクロです。
書く C の規格はマクロの名前で選びます。ISO C は c89 から c23、GNU 拡張つきは gnu89 から gnu23 という名前のマクロがあり、既存の .c ファイルを丸ごと取り込むときは include_c99 などのマクロを使います。
マクロ自体がコンパイラの役割を持つため、ビルドに C のツールチェーンは要らず、build.rs や cc、bindgen も使いません。ISO C の標準ヘッダーは同梱されています。
C の struct は #[repr(C)] の型に、関数は extern “C” fn に、グローバル変数は static になります。C の関数の呼び出しは unsafe ですが、関数に cinrs_safe の属性を付けると unsafe なしで生成され、rustc が変換結果を検査します。
生成されたトークンには元の C の位置が付いているので、cargo や rust-analyzer のエラーは C のコードの間違えた箇所を指します。
Real C, not a subset.
tanakh さん、GitHub の README
README に載っている計測では、c-testsuite の 98 %、GCC の torture テストの 89–93 %、Clang の C 適合テストの 82 % を正しく処理し、C プログラムの実行時間の中央値は gcc -O2 の 1.01× です。
展開結果が参照するのは core で(可変長配列には alloc、_Thread_local のオブジェクトには std が必要)、no_std のクレートでも使えます。同じ仕組みを GCC と同じコマンドラインで使える ccinrs というコマンドもあり、make CC=ccinrs のように C のプロジェクトのビルドに使えます。
料金とデータの置き場所
ライセンスは Apache License 2.0 と MIT ライセンスのどちらかを選べるデュアルライセンスです。
同じ分野のアプリ
| 名前 | 型 | 仕掛け | 対応 | 料金 |
|---|---|---|---|---|
| cinrs | C 埋め込みマクロ | Rust のファイルに書いた C をコンパイル中に Rust へ変換 | Rust(crates.io) | 無料(Apache-2.0 / MIT) |
| go-llama | Go ライブラリ | llama.cpp を WebAssembly 経由で純 Go に変換し、cgo なしで動かす | Go(cgo 不要、単一静的バイナリ) | 無料(MIT) |
| swift-asm-macro | Swift マクロ | Swift でインラインアセンブリを書いて関数を実装できる | Swift(macOS / iOS) | 無料(MIT) |
| ABIBridge | ネイティブ関数呼び出し | マングルされたシンボルをソース上の名前で解決し、Swift の型と値で呼べる | iOS / macOS / visionOS / watchOS / tvOS | 無料(MIT) |
入れる前に
Rust 1.99 以降が必要です。開発と全テストは Linux(x86-64)で行われ、macOS(arm64)と Windows(x86-64、MSVC)ではサンプルと移植可能なテストが push のたびにビルド・実行されています。
バージョン 0.1 の段階で、マクロの使い方はまだ変わる可能性があると README に書かれています。クロスコンパイルするクレートは、build.rs でターゲットを指定する必要があります。
setjmp/longjmp などは対応しておらず、位置つきのエラーになります。long double は double として扱われ、SIMD の組み込み関数は x86 のものです。また、マクロの呼び出しごとに別の翻訳単位になります。