首页 > 编程问答 >如何使用 Yocto / OpenEmbedded 构建 PyO3 扩展?

如何使用 Yocto / OpenEmbedded 构建 PyO3 扩展?

时间:2024-07-29 15:06:45浏览次数:10  
标签:python rust yocto openembedded pyo3

我有一个 Python/Rust 项目,它使用 PyO3 构建一个用 Rust 编写的 Python 扩展。

我用 maturin 设置了它,并且它在本地运行良好 - 它将构建一个轮子 (.whl) 并在其中构建是我的 Python 代码和 Rust 扩展共享对象,正如我所期望的那样。

我需要与 Yocto 交叉编译它(不幸的是,我被 Langdale 困住了),以将其放入我的嵌入式根文件系统中,我很快意识到我需要放弃 maturin for setuptools-rust ,因为 Yocto Langdale 根本没有 maturin 支持。

所以现在我的 Rust/Python/PyO3 项目是设置与 setuptools-rust 示例非常相似,我可以在本地构建它,生成的轮子包含我期望的内容。

目录布局:

.
├── Cargo.lock
├── Cargo.toml
├── pyproject.toml
├── python
│   └── my_project
│       └── my_module.py
└── src
    └── lib.rs

project.toml (部分):

[build-system]
requires = ["setuptools>=61.0.0", "setuptools_scm>=8", "setuptools-rust"]
build-backend = "setuptools.build_meta"

[tool.setuptools.packages]
find = { where = ["python"] }

[[tool.setuptools-rust.ext-modules]]
target = "my_project._lib"
path = "Cargo.toml"
binding = "PyO3"

Cargo.toml (部分):|| |但它不会在 Yocto 中构建,其配方类似于:

[lib]
name = "_lib"
crate-type = ["cdylib"]
path = "src/lib.rs"

[dependencies]
pyo3 = "0.22.0"

错误是:

inherit externalsrc
EXTERNALSRC = "${TOPDIR}/../../my_project"

inherit python_setuptools_build_meta

不知道该怎么做。看起来有时会出现 Python <3.11 和 Python 3.11 之间的 tomli drop-in 问题。

|   File "build/tmp/work/cortexa72-cortexa53-xilinx-linux/my_package/1.0-r0/recipe-sysroot-native/usr/lib/python3.10/site-packages/picobuild/__init__.py", line 93, in __init__
|     pyproject = tomllib.load(f)
| AttributeError: module 'tomli' has no attribute 'load'

在弄清楚我需要继承

而不是 python_setuptools3_rust 之后,我的 bitbake 配方现在看起来像这样: python_setuptools_build_meta 这似乎成功构建并打包了我项目的

inherit externalsrc
EXTERNALSRC = "${TOPDIR}/../../my_project"

inherit python_setuptools3_rust

Python 部分,但 Rust 扩展(我期望看到 .so 文件)完全不存在。| ||我已经浏览了 Yocto 日志,我可以看到对 .pyd 的引用(我猜是旧的构建方式),但没有任何特定于 Rust 的内容。我开始认为

太旧了,无法处理 python setup.py bdist_wheel ,但bbclass python_setuptools3_rust 似乎也无法构建它(由于tomli错误)。 pyproject.toml 此时我已经没有文档或示例来指导我了。 我对如何继续感到有点茫然。 python_setuptools_build_meta 我被 Yocto Langdale 困住了,这真是太遗憾了,因为最新的 LTS,Scarthgap,似乎确实有

支持。

It's a real shame I'm stuck with Yocto Langdale because the latest LTS, Scarthgap, does seem to have maturin support.


很遗憾你被困在 Yocto Langdale 上,因为它缺乏对 maturin 和更新的构建工具的支持确实让使用 PyO3 变得很棘手。不过,根据你提供的信息,让我们尝试解决这个问题。

看起来你已经能够解决 tomli 问题,并且你的 Yocto 配方现在正在使用 python_setuptools3_rust 类。然而,问题在于 Rust 扩展没有被构建。

以下是可能出错的地方以及我们如何调试的方法:

  1. setuptools-rust 配置:

  2. 缺少依赖项: 确保你的 Yocto 配方在构建时将 setuptools-rust 包含为依赖项。这通常是通过在你的配方的 DEPENDS RDEPENDS 中添加 python3-setuptools-rust 来完成的。

  3. Python 版本: setuptools-rust 1.2.0 以上版本支持使用 pyproject.toml 。确保你的 Yocto 构建环境中安装了正确版本的 setuptools-rust
  4. Cargo: 验证 cargo 是否在你的 Yocto 构建环境中可用,并且 setuptools-rust 能够找到它。你可能需要添加 cargo 包(例如, cargo-native )。

  5. Yocto 构建过程:

  6. 日志记录: 仔细检查 Yocto 构建日志以获取更多信息。寻找与 setuptools-rust cargo 或 Rust 构建相关的任何错误或警告。这可以提供有关扩展未构建原因的线索。

  7. 构建目录: 检查 Yocto 构建目录(通常是 build/tmp/work/…/your-package/ )。查找 Rust 扩展源( src/lib.rs )和 Cargo.toml 文件,以查看它们是否被正确复制到构建环境中。
  8. 手动构建: 作为最后的手段,尝试在 Yocto 构建环境中手动运行 python3 setup.py bdist_wheel 。这可以揭示任何特定的构建问题或配置错误。

  9. 解决方法(如果以上方法都不起作用):

  10. python_src_module 虽然这并不理想,但在 Yocto Langdale 中构建 PyO3 扩展的另一种方法是使用 python_src_module 类。这个类不太复杂,并且可能与旧版本的工具配合得更好。但是,你需要修改你的项目结构并手动处理一些构建步骤。

以下是使用 python_src_module 方法的简要示例:

  1. 将你的 Rust 代码移动到一个名为 src 的子目录中。
  2. 创建一个名为 setup.py 的文件,其中包含用于构建 Rust 扩展的基本指令。
  3. 在你的 Yocto 配方中,继承 python_src_module 并设置 S = "${WORKDIR}/src"

以下是修改后的 setup.py 的示例:

from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext
import subprocess

class BuildExt(build_ext):
    def run(self):
        subprocess.check_call(['cargo', 'build', '--release'], cwd='src')
        super().run()

setup(
    name='my_project',
    version='1.0',
    ext_modules=[
        Extension('my_project._lib', ['src/lib.rs']),
    ],
    cmdclass={'build_ext': BuildExt},
)

请记住,这只是一个基本的示例,你可能需要根据你的项目结构和依赖项进行调整。

调试 Yocto 构建问题可能很棘手且耗时。希望这些建议可以帮助你找到问题的原因并解决它,或者至少让你走上正确的轨道。

标签:python,rust,yocto,openembedded,pyo3
From: 78805524

相关文章

  • 使用 Python 中的多处理防止共享内存中的数据损坏?
    我目前正在开发一个多处理Python程序,其中每个进程将其索引作为连续的4字节整数写入共享内存。并且有一个读取器可以在没有任何锁的情况下读取其他进程的索引。因为我没有使用任何同步原语,所以我担心读取器进程可能会由于逐字节写入内存而读取损坏的数据(例如,一个索引的前2个......
  • Python如何统治AI世界?一文读懂它的优势与挑战
    一、Python语言介绍1.1Python语言概述Python是一种由GuidovanRossum于1991年首次发布的高级编程语言。其设计理念强调代码的可读性和简洁性,使其成为了许多开发者的首选语言。Python的语法简洁直观,采用了缩进来定义代码块,这与其他使用花括号或关键词的编程语言不同。Python......
  • 找到一种方法将program1的输出作为python中program2的输入发送
    有人可以帮我找到一种方法将program1的输出作为python中的program2的输入发送将其保存为.csv文件不会对我有帮助,因为该程序应该尽快执行这些任务。因此我正在寻找一种方法将程序1的终端输出直接发送到程序2在Python中,可以使用子进程模块将一个程序的输出发送到另一个程......
  • 同时运行多个Python程序的最佳方法
    我有一个python程序,我想同时运行多个具有不同参数的实例。这些实例彼此之间不进行通信。在单独的终端中运行每个实例太乏味了。我考虑使用多处理模块将每个实例作为单独的进程运行,但是我希望能够随时停止和重新启动某些单独的实例,而不会中断其他正在运行的实例。是否有任何流程......
  • 替换 Python 数据框中包含值的 <
    我有一个数据框,在某些列中存在诸如“<0.5、<10、<100”等值。如果值仅包含“<”,我想将所有这些值替换为0。我该怎么做?我对Python比较陌生。尝试使用pd.DataFrame.replace()。importpandasaspd#创建示例数据框df=pd.DataFrame({'A':['<0.5','<10',15,20],......
  • 基于funasr+pyaudio实现电脑本地麦克风实时语音识别项目语音转文本python实现
    【框架地址】https://github.com/modelscope/FunASR【简单介绍】FunASR是一个功能全面的语音识别工具包,支持多种预训练模型的推理和微调,提供高精度和高效能的语音识别服务。结合PyAudio库,可以实现电脑本地麦克风实时语音识别项目。该项目首先通过PyAudio库捕获麦克风输入的......
  • 从Python中的数据框中删除不必要的数据
    所以我这里有一个dat文件,我正在使用Python来读取它。在整个文件中,有一些不必要的行,例如BEGIN等,而我真正想开始阅读的部分是从数据帧开始。因此,我想检查在Python中执行此操作的最佳方法是什么,并且只阅读数据框何时开始?谢谢!以下是使用Python从数据......
  • Python拟合曲线
    拟合曲线多项式拟合np.ployfit(x,y,deg)importmatplotlib.pyplotaspltimportnumpyasnpx=[1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8]y=[33.40,79.50,122.65,159.05,189.15,214.15,238.65,252.2,267.55,280.50,296.65,301.65,310.......
  • 12个Python数据类型转换实战演练
    文末赠免费精品编程资料~~在Python编程中,数据类型转换是处理数据时必不可少的技能。掌握如何灵活地在不同类型之间转换,能让你的代码更加高效和灵活。下面,我们将通过一系列实战演练,学习并实践12种常见的Python数据类型转换。1.整数转字符串实战案例:将年龄转换为字符串......
  • Python全套教程,小白零基础入门必备!
    Python是一种语法简单、功能强大的编程语言,它注重的是如何高效解决问题。【教程领取方式在文末!!】正是这种简单实用的特性,让Python成为近年来最热门的编程语言之一。Python具有广泛的应用场景,包括:Web开发、数据分析、机器学习、网络爬虫、人工智能、量化交易等众多领......