「cinrs」でRustにCを直書きしたら、build.rsが要らなくなった

cinrs
Rust のファイルに直接書いた C のコードを、コンパイル中に Rust へ変換して使えるようにするマクロ
GitHub
公開
正式公開 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 ライセンスのどちらかを選べるデュアルライセンスです。

同じ分野のアプリ

名前型仕掛け対応料金
cinrsC 埋め込みマクロRust のファイルに書いた C をコンパイル中に Rust へ変換Rust(crates.io)無料(Apache-2.0 / MIT)
go-llamaGo ライブラリllama.cpp を WebAssembly 経由で純 Go に変換し、cgo なしで動かすGo(cgo 不要、単一静的バイナリ)無料(MIT)
swift-asm-macroSwift マクロ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 のものです。また、マクロの呼び出しごとに別の翻訳単位になります。