如何限制bindgen仅为自定义C库生成绑定,排除标准库函数?
问题
我正尝试使用bindgen为某C库生成Rust绑定。已编写wrapper.h文件,仅引入该库的必要头文件(#include <mylib/mylib.h>),build.rs中的bindgen使用代码如下:
let bindings = bindgen::Builder::default() .clang_arg("-I/opt/mylib/usr/local/include") .header("wrapper.h") .wrap_static_fns(true) .generate() .expect("Unable to generate bindings");
但该C库调用了strcpy等标准函数,导致bindgen同时生成了自定义库和标准库(如strcpy、malloc)的绑定。我希望仅生成自定义库mylib的函数与类型绑定,该如何实现?
我尝试的方案:在mylib的sys crate中生成绑定,通过lib.rs仅暴露所需函数:
mod bindings { include!(concat!(env!("OUT_DIR"), "/bindings.rs")); } pub use bindings::my_external_function;
此方法可实现所需暴露效果,但不确定是否为最优解。
解决方案
方法1:用bindgen白名单精准控制生成内容(推荐)
bindgen自带白名单配置API,能直接在生成阶段只保留目标库的符号,从根源上避免生成标准库或无关绑定。
修改build.rs如下:
let bindings = bindgen::Builder::default() .clang_arg("-I/opt/mylib/usr/local/include") .header("wrapper.h") .wrap_static_fns(true) // 匹配mylib的函数,按实际命名前缀调整正则 .allowlist_function("my_.*") // 匹配mylib的类型/结构体/枚举 .allowlist_type("My.*") // 若有全局常量,可添加此规则 .allowlist_var("MY_.*") .generate() .expect("Unable to generate bindings");
根据mylib的符号命名规则调整正则表达式即可,比如所有函数以mylib_开头就用"mylib_.*"。这种方式生成的bindings.rs会非常简洁,后续也不用手动筛选暴露的符号,是最优解。
方法2:手动筛选暴露符号(你的现有方案)
你现在用的在sys crate里通过pub use手动暴露所需符号的方法是可行的,也是Rust生态中sys crate的常规做法——先生成完整绑定,再向上层暴露必要API。但缺点是生成的bindings.rs会包含大量无关内容,略微增加编译时间和二进制体积;如果mylib API较多,手动维护pub use会比较麻烦。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

