ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RustPython 嵌入 Rust 应用时如何用 freeze-stdlib 冻结 Python 标准库?

RustPython 嵌入 Rust 应用时如何用 freeze-stdlib 冻结 Python 标准库? RustPython 嵌入 Rust 应用时如何用 freeze-stdlib 冻结 Python 标准库【免费下载链接】RustPythonA Python Interpreter written in Rust项目地址: https://gitcode.com/GitHub_Trending/ru/RustPython把 RustPython 嵌入 Rust 应用时解释器要能运行 Python 代码就必须有 Python 标准库可用。RustPython 提供的freeze-stdlibcargo feature 可以解决这个问题它把标准库的 Python 部分编译成字节码并冻结进你的二进制里运行时不再依赖随附的Lib/目录。仓库中的示例项目 example_projects/frozen_stdlib 完整演示了这条路径本文按它讲解如何在自己的 Rust 工程里开启freeze-stdlib并验证冻结后的标准库确实生效。freeze-stdlib 的作用与 feature 链rustpython-pylibcrate 的文档注释说明了最常见的用法给rustpython-vm加上freeze-stdlibfeature就能自动把标准库的 Python 部分包含进二进制见 crates/pylib/src/lib.rs。开启该 feature 后pylib 会生成冻结字节码常量#[cfg(feature freeze-stdlib)] pub const FROZEN_STDLIB: rustpython_compiler_core::frozen::FrozenLib rustpython_derive::py_freeze!(dir ../Lib, crate_name rustpython_compiler_core);各 crate 之间的 feature 依赖关系如下均来自各自的Cargo.toml根包rustpythonfreeze-stdlib [stdlib, rustpython-vm/freeze-stdlib, rustpython-pylib?/freeze-stdlib]Cargo.tomlrustpython-vmfreeze-stdlib [encodings]crates/vm/Cargo.tomlrustpython-pylibfreeze-stdlib [dep:rustpython-compiler-core, dep:rustpython-derive]crates/pylib/Cargo.toml。也就是说freeze-stdlib会在构建期引入编译器和 derive 宏把Lib/目录下的 Python 源码编译成冻结字节码。准备条件仓库 workspace 声明rust-version 1.95.0Cargo.toml使用 RustPython 的 workspace 时工具链需满足该版本要求。配置依赖开启 freeze-stdlib feature示例项目的 example_projects/frozen_stdlib/Cargo.toml 展示了嵌入方需要的三个依赖全部关闭默认 feature 并显式打开freeze-stdlib[dependencies] rustpython { path ../../, default-features false, features [freeze-stdlib] } rustpython-vm { path ../../crates/vm, default-features false, features [freeze-stdlib] } rustpython-pylib { path ../../crates/pylib, default-features false, features [freeze-stdlib] }注意两点这里的path是示例项目位于 RustPython 仓库内部时使用的相对路径分别指向仓库根目录和crates/下的子 crate。在你自己的工程里需要把它们替换成你 RustPython 源码的实际位置示例工程末尾有一个空的[workspace]段用于让该项目独立于外层 RustPython workspace 构建。初始化解释器两种写法example_projects/frozen_stdlib/src/main.rs 演示了两种等价路径按你的依赖选择其一即可。路径一rustpython::InterpreterBuilderuse rustpython::InterpreterBuilderExt; fn interpreter_with_config() { let interpreter rustpython::InterpreterBuilder::new() .init_stdlib() .interpreter(); // Use interpreter.enter to reuse the same interpreter later interpreter.run(|vm| run(rustpython::InterpreterBuilder, vm)); }InterpreterBuilder::new().init_stdlib()负责把冻结的标准库装进解释器interpreter.run(|vm| ...)执行一次解释器会话代码注释提示也可以用interpreter.enter之后复用同一个解释器。路径二rustpython_vm::Interpreter::builderuse rustpython_vm::{PyResult, VirtualMachine}; fn interpreter_with_vm() { let interpreter rustpython_vm::Interpreter::builder(Default::default()) .add_frozen_modules(rustpython_pylib::FROZEN_STDLIB) .build(); // Use interpreter.enter to reuse the same interpreter later interpreter.run(|vm| run(rustpython_vm::Interpreter::builder, vm)); }这条路径更底层通过add_frozen_modules显式注入rustpython_pylib::FROZEN_STDLIB这个冻结字节码常量。两种写法的main()都依次调用用来分别验证各自的初始化路径。验证冻结的标准库可用示例的run函数用标准库的json模块做功能验证fn run(keyword: str, vm: VirtualMachine) - PyResult() { let json vm.import(json, 0)?; let json_loads json.get_attr(loads, vm)?; let template r#{key: value}#; let json_string template.replace(value, keyword); let dict json_loads.call((vm.ctx.new_str(json_string),), vm)?; vm.print((dict,))?; Ok(()) }判断方式很直接如果冻结标准库生效vm.import(json, 0)与json.loads调用都会成功程序打印json.loads解析出的 dict其中key对应的值是运行时传入的keyword示例里分别是rustpython::InterpreterBuilder和rustpython_vm::Interpreter::builder如果 feature 没配好、标准库没被冻结import json这一步就会以PyResult::Err失败。可选同时冻结你自己的 Python 文件如果你的应用不止要用标准库还要捆绑自己的 Python 代码仓库提供了vm::py_compile!宏见 examples/freeze/main.rsvm::Interpreter::without_stdlib(Default::default()).enter(run) // the file parameter is relative to the current file. let module vm::py_compile!(file freeze.py); let res vm.run_code_obj(vm.ctx.new_code(module), scope);py_compile!的file参数相对当前的 Rust 源文件定位示例冻结的是 examples/freeze/freeze.py在构建期把该文件编译进二进制。这个示例刻意使用Interpreter::without_stdlib启动解释器只跑冻结的模块。如果要嵌入一整个 Python 项目仓库指向了 aheui-rust 的rpaheuicrate 作为参考见 example_projects/aheui-rust.md该文档有一个明确提醒冻结流程不会自动解析依赖如果你的依赖超出标准库范围需要把这些依赖一并冻结。可选构建 WASI 模块README 的 WASI 章节展示了freeze-stdlib的典型应用场景之一——编译出不依赖外部标准库的 WebAssembly 模块README.md# 只需执行一次 rustup target add wasm32-wasip1 cargo build --target wasm32-wasip1 --no-default-features --features freeze-stdlib,stdlib --releaseREADME 明确说明这里使用freeze-stdlib是为了把标准库包含进二进制产物随后可用 wasmer 运行例如wasmer run --volumepwd-- target/wasm32-wasip1/release/rustpython.wasmpwd/extra_tests/snippets/stdlib_random.py。限制与边界freeze-stdlib会连带开启stdlib根包层面和encodingsvm 层面依赖配置里用default-features false时这些不会自动生效需要按示例显式声明冻结发生在构建期基于Lib/目录编译字节码运行环境不需要携带 Python 标准库文件自定义 Python 文件的冻结py_compile!/ 整项目嵌入不解析 Python 侧依赖超出标准库的第三方模块必须自行冻结否则会缺少模块。【免费下载链接】RustPythonA Python Interpreter written in Rust项目地址: https://gitcode.com/GitHub_Trending/ru/RustPython创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表