-
Notifications
You must be signed in to change notification settings - Fork 801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Generalize the rpath API for relocatable Python installations #4890
base: main
Are you sure you want to change the base?
Conversation
Relocatable Python installations like python-build-standalone have a similar need for an rpath as the macOS framework builds in Xcode. Furthermore, the platform on which you build your code is not really a function of the code itself. This change generalizes the recent `add_python_framework_link_args()` from PyO3#4833 to `add_python_link_args()`, which also does the right thing on python-build-standalone, and encourages everyone to set up a build.rs file that invokes it, whether or not they need it on their current machine.
The reason I think this is the right approach is that it's needed for macOS anyway. We could do something else on the python-build-standalone or uv side, but it still seems worthwhile to have everyone include the build.rs file so that their code builds on macOS. A couple of alternatives (that wouldn't address the macOS need):
Asking every user to create a build.rs is a little annoying but it seems to be the best path here. (And maybe if someone figures out a good design for rust-lang/cargo#9554, we can go back to not requiring a build.rs.) |
I'm not sure there's appetite for this, since it's a big migration. Could there be a way to opt out for packages using the abi3 feature? Then at least there's an escape hatch for people that don't have a lot of stomach for managing packaging. While spinning up on PyO3 I did notice that needing to opt in to depending on It'd be nice to add some tests using |
Or I guess, using |
As I understand it, abi3 is only usable by extension modules loaded into Python, and not usable by Rust code loading libpython (because how do you know which libpython are you going to use), right? Which means that If that's already the case, then yes, this is unnecessary for abi3 users. (Mostly my thinking was that it's good for people to be able to write tests; if they already can't write tests, then that argument doesn't apply.) As I understand it, the rpath is not required by extension modules, regardless of whether they use abi3, regardless of platform (in particular, I believe the existing I can double-check all these claims.
To be clear I'm also relatively new to PyO3, but, I think if we tell people "in order to use pyo3, you need a build.rs file that does So I'm thinking that where the docs say, "to get started with pyo3, add this line to your Cargo.toml", they'll now say, "add these three lines to your Cargo.toml and create this three-line build.rs," and then people won't have to think about that as their project gets more complex / as they find some more unusual build scenario. I'm happy to create that |
I think people tend to use e.g. pytest to manage tests and not use cargo test at all. See https://pyo3.rs/v0.14.4/faq.html#i-cant-run-cargo-test-im-having-linker-issues-like-symbol-not-found-or-undefined-reference-to-_pyexc_systemerror and |
Relocatable Python installations like python-build-standalone have a similar need for an rpath as the macOS framework builds in Xcode. Furthermore, the platform on which you build your code is not really a function of the code itself. This change generalizes the recent
add_python_framework_link_args()
from #4833 toadd_python_link_args()
, which also does the right thing on python-build-standalone, and encourages everyone to set up a build.rs file that invokes it, whether or not they need it on their current machine.The motivation here is #4813 and astral-sh/uv#11006: currently,
cargo test
doesn't work if your test cases call into libpython and your libpython isn't installed systemwide.I'm opening this now to get feedback on the general approach of encouraging everyone to have a build.rs file regardless of whether they currently need it. This needs some more docs changes to convey that. If this sounds good, I also plan to contribute a change to
maturin new
to create this file.At the moment the heuristic for whether your Python installation needs the rpath setting is whether there's a
sysconfig.get_var("PYTHON_BUILD_STANDALONE") == "1"
. We're planning on trying to get a mode in upstream CPython to build a relocatable installation (mostly to buildbin/python
itself with$ORIGIN
-relative rpaths, but also to get libpython to detect some things about its own path better), at which point it would make sense to add an official sysconfig var to designate relocatability. Until then I think a heuristic is the best we can do. I suppose we can unconditionally emit an rpath line but having an rpath for system directories like /usr/lib is pretty weird.Test case: download some recent python-build-standalone build, add its bin directory to the front of your
PATH
, and try to runcargo test
on, sayThis currently fails, but works with this patch. (It does not work with a stock python-build-standalone build if you set
PYO3_PYTHON
instead of adding to yourPATH
, which is a bug; it does work with a Python installed byuv
, which does some post-install tweaks.)