Skip to main content

Crate libperl_macrogen

Crate libperl_macrogen 

Source
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::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 in PerlvarDict.
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
統一型表現モジュール