Expand description
§libperl-macrogen
Generate Rust FFI bindings for the things bindgen can’t see:
C macro functions and static inline definitions in
Perl’s header tree.
rust-bindgen is the standard for translating C declarations to
Rust, but it deliberately skips macro-shaped function definitions
(because they have no fixed type signature) and produces no Rust
body for static inline functions (because their definitions live
in headers, not the linked library). For wrapping libperl that
gap is huge — much of the public-looking API (SvIV, newRV_inc,
PL_stack_base, hundreds more) is exposed as macros or
static inline only.
libperl-macrogen complements bindgen: it lex / parse /
type-infers the relevant headers and emits Rust wrappers like
pub unsafe fn SvIV(my_perl: *mut PerlInterpreter, sv: *mut SV) -> IV {
unsafe { Perl_SvIV(my_perl, sv) }
}plus declarative macros for PERLVAR-driven globals (so the same
PL_stack_base!(my_perl) source compiles against threaded and
non-threaded Perl).
§Library API
The high-level entry point is the Pipeline builder, which
drives a header file through the preprocess → infer → codegen
stages and writes a Rust source file:
use libperl_macrogen::Pipeline;
let mut output = std::fs::File::create("macro_bindings.rs")?;
Pipeline::builder("xs-wrapper.h")
.with_auto_perl_config()?
.with_bindings("bindings.rs") // bindgen output for type info
.with_codegen_defaults()
.build()?
.generate(&mut output)?;See PipelineBuilder for the full set of options
(skip-list, extra include paths, codegen knobs, …).
§CLI
Installing the crate also gives you a libperl-macrogen binary
for one-off / inspection use. Run with --help for the option
summary.
§Apidoc data
The crate bundles a pre-extracted snapshot of perlapi documentation
(apidoc.tar.gz, ~1.9 MiB compressed) that the type inferencer
consults during macro-wrapper generation. This means no network
access is required at build time — works under docs.rs’s
--network none sandbox, in air-gapped CI, etc.
For advanced use (e.g. testing an unreleased apidoc dataset on an
offline mirror), set the LIBPERL_APIDOC_URL environment variable
to override and download from there instead.
§Status
Pre-1.0 — focused on the libperl-rs use case. Wider header-tree coverage and stable APIs come after libperl-rs hits 1.0.
Re-exports§
pub use apidoc::find_apidoc_dir_from;pub use apidoc::resolve_apidoc_path;pub use apidoc::ApidocArg;pub use apidoc::ApidocCollector;pub use apidoc::ApidocDict;pub use apidoc::ApidocEntry;pub use apidoc::ApidocFlags;pub use apidoc::ApidocResolveError;pub use apidoc::ApidocStats;pub use apidoc::Nullability;pub use infer_api::run_inference_with_preprocessor;pub use infer_api::DebugOptions;pub use infer_api::InferConfig;pub use infer_api::InferError;pub use infer_api::InferResult;pub use infer_api::InferStats;pub use infer_api::TypedefDict;pub use error::CompileError;pub use error::DisplayLocation;pub use error::LexError;pub use error::PPError;pub use error::ParseError;pub use error::Result;pub use fields_dict::FieldsDict;pub use inline_fn::InlineFnDict;pub use intern::InternedStr;pub use intern::StringInterner;pub use rust_decl::RustDeclDict;pub use lexer::IdentResolver;pub use lexer::Interning;pub use lexer::Lexer;pub use lexer::LookupOnly;pub use lexer::MutableLexer;pub use lexer::ReadOnlyLexer;pub use macro_def::MacroDef;pub use macro_def::MacroKind;pub use macro_def::MacroTable;pub use macro_infer::convert_assert_calls_in_compound_stmt;pub use macro_infer::detect_assert_kind;pub use macro_infer::InferStatus;pub use macro_infer::MacroInferContext;pub use macro_infer::MacroInferInfo;pub use macro_infer::MacroInferStats;pub use macro_infer::NoExpandSymbols;pub use macro_infer::ParseResult;pub use parser::parse_expression_from_tokens;pub use parser::parse_expression_from_tokens_ref;pub use parser::parse_type_from_string;pub use parser::Parser;pub use perl_config::build_pp_config_for_perl;pub use perl_config::get_default_target_dir;pub use perl_config::get_perl_config;pub use perl_config::get_perl_version;pub use perl_config::PerlConfig;pub use perl_config::PerlConfigError;pub use perlvar_dict::ArrayLength;pub use perlvar_dict::PerlvarCollector;pub use perlvar_dict::PerlvarDict;pub use perlvar_dict::PerlvarEntry;pub use perlvar_dict::PerlvarKind;pub use preprocessor::CallbackPair;pub use preprocessor::CommentCallback;pub use preprocessor::MacroCalledCallback;pub use preprocessor::MacroCallWatcher;pub use preprocessor::MacroDefCallback;pub use preprocessor::PPConfig;pub use preprocessor::Preprocessor;pub use semantic::SemanticAnalyzer;pub use semantic::Symbol;pub use semantic::SymbolKind;pub use semantic::Type;pub use sexp::SexpPrinter;pub use sexp::TypedSexpPrinter;pub use source::FileId;pub use source::FileRegistry;pub use source::SourceLocation;pub use token::Comment;pub use token::CommentKind;pub use token::Token;pub use token::TokenKind;pub use token_source::TokenSlice;pub use token_source::TokenSliceRef;pub use token_source::TokenSource;pub use type_env::ParamLink;pub use type_env::TypeConstraint;pub use type_env::TypeEnv;pub use type_repr::CDerivedType;pub use type_repr::CPrimitiveKind;pub use type_repr::CTypeSource;pub use type_repr::CTypeSpecs;pub use type_repr::InferredType;pub use type_repr::IntSize as TypeReprIntSize;pub use type_repr::RustPrimitiveKind;pub use type_repr::RustTypeRepr;pub use type_repr::RustTypeSource;pub use type_repr::TypeRepr;pub use unified_type::IntSize;pub use unified_type::SourcedType;pub use unified_type::TypeSource;pub use unified_type::UnifiedType;pub use rust_codegen::CodegenConfig;pub use rust_codegen::CodegenDriver;pub use rust_codegen::CodegenStats;pub use rust_codegen::GeneratedCode;pub use rust_codegen::GenerateStatus;pub use rust_codegen::RustCodegen;pub use pipeline::Pipeline;pub use pipeline::PipelineBuilder;pub use pipeline::PipelineError;pub use pipeline::PreprocessConfig;pub use pipeline::InferConfig as PipelineInferConfig;pub use pipeline::CodegenConfig as PipelineCodegenConfig;pub use pipeline::PreprocessedPipeline;pub use pipeline::InferredPipeline;pub use pipeline::GeneratedPipeline;pub use ast::*;
Modules§
- apidoc
- Perl Apidoc Format Parser
- apidoc_
data - Embedded apidoc data management
- apidoc_
patches - Apidoc patches: data-driven corrections for known perl source bugs
- ast
- C言語の抽象構文木
- c_
fn_ decl - C 関数宣言辞書
- enum_
dict - Enum バリアント辞書
- error
- fields_
dict - 構造体フィールド名辞書
- global_
const_ dict - Global static const declaration の捕捉
- infer_
api - マクロ型推論の高レベル API
- inline_
fn - inline 関数辞書
- intern
- lexer
- macro_
def - マクロ定義と管理
- macro_
infer - マクロ型推論エンジン
- parser
- C言語パーサー
- perl_
config - Perl Config.pm から設定を取得するモジュール
- perlvar_
dict PerlvarDict— collected PERLVAR/PERLVARI/PERLVARA/PERLVARIC entries.- perlvar_
emitter - Emit
PL_<name>!($my_perl)declarative macros for each entry inPerlvarDict. - pipeline
- Pipeline API for libperl-macrogen
- pp_expr
- プリプロセッサ条件式の評価
- preprocessor
- Cプリプロセッサ
- rust_
codegen - Rust コード生成モジュール
- rust_
decl - Rust宣言パーサー
- semantic
- 意味解析モジュール
- sexp
- S-expression形式でのAST出力
- source
- static_
array_ emitter GlobalConstDictの静的 const 配列を Rust のstatic配列定義として 出力する。- struct_
emitter - 構造体・union 定義の Rust ソース生成
- syn_
codegen - syn::Expr ベースの Rust コード生成モジュール
- token
- token_
source - トークンソースの抽象化
- type_
env - 型環境・制約管理モジュール
- type_
repr - 型表現モジュール
- unified_
type - 統一型表現モジュール