Open hroncok opened 1 month ago
Is this the only test that fails? As far as I can tell, Python segfaults when executing the extension module initialization function. The module is extremely simple https://github.com/mesonbuild/meson-python/blob/main/tests/packages/link-against-local-lib/examplemod.c, thus I don't see how this is possible other than because of a bug in CPython. The other possibility is a bug in the packaging: if you end up with the Python headers and the installed Python having a different opinion about the shape of the PyModuleDef
structure. Or something like this.
Is this the only test that fails?
Yes. Another one fails with https://github.com/pytest-dev/pytest-mock/issues/468
Huh, I can even reproduce this with Python 3.13.0 and 3.12.7. Possibly this is a problem in binutils etc.
I can reproduce the crash with binutils 2.43.50 but not with binutils 2.43.1.
I'll take that to Fedora's binutils maintainer.
Should I keep this open or close it?
Should I keep this open or close it?
Looks unrelated to meson-python, so it'd make sense to close this. If you prefer to keep it open for some days until you receive a reply on the binutils
bug report, that seems fine as well.
For the record, the binutils folks say this is a problem in patchelf. They are also quite determined that patchelf cannot be supported and would rather see meson-python utilize the final -Wl,-rpath=…
option when building the extension module.
Reopening to keep it visible, since it doesn't sound like a fix in either binutils
or patchelf
is in the work just yet.
They are also quite determined that patchelf cannot be supported and would rather see meson-python utilize the final -Wl,-rpath=… option when building the extension module.
Using the final -Wl,-rpath
doesn't seem possible, since meson-python
isn't actually building the extension module - meson
is. And the package author (who could add an rpath argument to the package itself) doesn't know where and how meson-python
will vendor the shared library into the wheel.
If the problem is RPATH rewriting though, this isn't just going to show up in this test case (which is a little niche and for a scenario that possibly is unused in the real world so far - not sure). auditwheel
is doing the same when it vendors external shared libraries into wheels distributed on PyPI. That isn't going to show up in bug reports very soon only because auditwheel
is usually run in a manylinux
container that doesn't have a recent binutils
. But that's an important use case for patchelf
. And Nix will need it as well I'm sure.
It's still a little unclear to me what triggers the bug exactly, but it seems like this has to be fixed either in patchelf
or in binutils
.
I just read through the whole thread at https://bugzilla.redhat.com/show_bug.cgi?id=2321588. A few comments:
LD_LIBRARY_PATH
is useless (that means the wheel is broken by default)libdir
location for shared libraries, and (b) the need to make Python wheels portable and installable into venv's that don't have a predefined absolute install path on the user's OS. This makes relocating shared libraries a necessary step, and it's common to tooling for Python wheels, Nix packages, Conda packages, etc. It looks to me like saying "use -Wl,-rpath=/final/install/location
" misses that key point.Also, thanks for trying to sort this out @hroncok! Doesn't look like an easy conversation.
-Wl,-rpath=/final/install/location
technically, this path is relative, so we don't have that exact problem. If meson-python could "tell" meson to use a particular path, that should work, no?
There appears to be a kind of weirdly layered confusion going on here across multiple issue trackers.
"meson-python" happens to use patchelf, which uncovered a bug in the (uncoordinated) interaction between binutils snapshots (?) used distro-wide in fedora, and patchelf, a program widely used in various contacts. As noted in the fedora ticket, binutils has broken the PyPy build as well.
This bug doesn't need pip to replicate it, I'm sure. You could use python -m build
, available on PyPI as "build", instead of pip install. It will create a wheel for you. And "build" assumes developer intent already, which means no passing --verbose to pip.
Patchelf is needed by literally anyone building wheels with C libraries for upload to PyPI and usage by basically all Linux users on any distro. Fedora and its derivatives are actually quite popular for this due to GCC Toolset, which allows you to use new GCC versions with older glibc... So having this broken on fedora specifically, seems a bit unfortunate!
Why is it needed, you ask? Well, it's needed because uploading to PyPI is a subcategory of building standalone binaries, so there's a program whose sole purpose is to modify your wheels, copy system libraries into the wheel, use patchelf to retarget everything to use relative rpaths that are part of the wheel layout, and upload the now standalone python modules.
This is a serious use case and complaining that meson-python should just not do that when using its own libraries, is missing the point (even though as a meson maintained, not a meson-python maintainer, I am sympathetic to this argument). Less blame, more investigating whether patchelf and binutils can get along, please.
The problem is fundamentally about (a) the way Python wheels are standardized and are not containing a libdir location for shared libraries, and (b) the need to make Python wheels portable and installable into venv's that don't have a predefined absolute install path on the user's OS. This makes relocating shared libraries a necessary step, and it's common to tooling for Python wheels, Nix packages, Conda packages, etc. It looks to me like saying "use
-Wl,-rpath=/final/install/location
" misses that key point.
@rgommers, note that this actually isn't about being relocatable. It's about changing the install layout at all. Being relocatable just means you need an rpath string using $ORIGIN
(this is a dynamic loader variable) and the knowledge at the time of linking, what relocatable layout you need. You can then just inject the string value in LDFLAGS.
It doesn't help because you will potentially still have other unwanted rpath entries, and you can't handle library dependencies that aren't part of meson.build -- that's why auditwheel uses patchelf too, isn't it?
And actually injecting LDFLAGS is difficult to do robustly since if you do it in the environment it will be ignored when the user specified a native file, and if you do it via a native file you scribble all over the user LDFLAGS and the user native files.
Less blame, more investigating whether patchelf and binutils can get along, please.
I am not blaming anybody here. I am merely trying to solve this problem.
I am well aware that even if meson-python stops using patchelf, we will have this problem with auditwheel etc.
@rgommers, note that this actually isn't about being relocatable. It's about changing the install layout at all.
You're right. I never encountered any other reasons for changing the install layout, so in my mind the two meant roughly the same thing.
Being relocatable just means you need an rpath string using
$ORIGIN
Yes indeed. I just wrote docs for using shared libraries in gh-700, and for internal ones it starts with explaining how to use $ORIGIN
. Being able to do so is relatively rare though, since shared libraries that are only meant for being included in a Python wheel are quite uncommon. The more typical case is something like this:
c-or-cpp-lib/
meson.build # contains shared_library() or library()
python-bindings/
meson.build # contains extension module linking against shared library
other-lang-bindings/
...
In such cases, especially if the Python bindings are maintained by other people than the C/C++ core, it may not be acceptable to mess with how the C/C++ is compiled specifically to make Python wheel builds nicer. The failing test case at hand here is representative for that: the shared library goes to libdir
, and meson-python
is left to do the "vendoring" work a la auditwheel
.
In gh-700 I'm also adding more test cases, including for the $ORIGIN
case. One that is still missing is for an external shared library + auditwheel
- that may be useful as well.
Hello.
I am trying to build and test meson-python with Python 3.14 in Fedora.
I see a strange Segmentation fault in test_local_lib. I can reproduce it on Fedora Rawhide (42), but not on Fedora 39.
To reproduce: