I have a Python/Rust project that uses PyO3 to build a Python extension, written in Rust.
I have it set up with maturin
and it works fine locally – it will build a wheel (.whl) and within that is my Python code and the Rust extension shared object, just as I’d expect.
I need to cross-compile this with Yocto (I’m stuck with Langdale, unfortunately), to put it in my embedded root filesystem, and I’ve quickly come to the realisation that I will need to ditch maturin
for setuptools-rust
, as there is no maturin
support in Yocto Langdale at all.
So now my Rust/Python/PyO3 project is set up very much like the setuptools-rust
example and I can build it locally, and the generated wheel contains what I’d expect.
Directory layout:
.
├── Cargo.lock
├── Cargo.toml
├── pyproject.toml
├── python
│ └── my_project
│ └── my_module.py
└── src
└── lib.rs
project.toml
(partial):
[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
(partial):
[lib]
name = "_lib"
crate-type = ["cdylib"]
path = "src/lib.rs"
[dependencies]
pyo3 = "0.22.0"
But it doesn’t build in Yocto with a recipe similar to:
inherit externalsrc
EXTERNALSRC = "${TOPDIR}/../../my_project"
inherit python_setuptools_build_meta
The error is:
| 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'
Not sure what to make about that. It looks something that tomli drop-in issue between Python <3.11 and Python 3.11 one sees sometimes.
After working out that I needed to inherit from python_setuptools3_rust
instead of python_setuptools_build_meta
, my bitbake recipe now looks something like this:
inherit externalsrc
EXTERNALSRC = "${TOPDIR}/../../my_project"
inherit python_setuptools3_rust
What this seems to do is successfully build and package the Python parts of my project, but the Rust extension (I expected to see a .so
or .pyd
file) is completely absent.
I’ve been through the Yocto logs and I can see references to python setup.py bdist_wheel
(the old way to build, I guess), but nothing Rust-specific. I’m starting to think that python_setuptools3_rust
is too old to handle pyproject.toml
, but the bbclass python_setuptools_build_meta
doesn’t seem to be able to build it either (due to that tomli error).
At this point I’ve run out of documentation or examples to guide me. I’m at a bit of a loss as to how to proceed.
It’s a real shame I’m stuck with Yocto Langdale because the latest LTS, Scarthgap, does seem to have maturin
support.