-
-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
libpython3.so doesn't contain any symbols (stable ABI), cannot link to it. #104612
Comments
This is indeed a bug now.
This is introduced 12 yrs ago. My guess would be the toolchain has evolved in these years. Linkers nowadays cannot resolve symbols from the dependencies of a shared library. I need to consult some linker experts. Before we figure out a solution, link to the Updated: |
Cannot we just copy the |
The soname is different. |
Did this ever work? I tried playing with this a bit, and can confirm the report is reproducible (with a fresh build from main branch, as well as with a copy of python 3.6 I happened to have around), using gcc 8.5 on Red Hat Linux. With a certain combination of flags and setting LD_LIBRARY_PATH for the gcc invocation itself, it looked like the linker was at least aware of the existence of the linked libpython, but it refused to add symbols from it if it's not explicitly included in the command line:
Some things that "worked": Include both python3 and python3.12: this results both so's included in the DT NEEDED of the binary
and if I patchelf the binary to drop libpython3.12.so, it still works at runtime because of the transitive dependency
but if we're going through that trouble, then this would be equivalent and arguably cleaner:
Potentially the simplest workaround is to delete the "useless" libpython3.so and replace it with a symlink:
This still leaves us with a binary that specifies the 3.12 DSO, because that's the soname we link against
which brings us back to patchelf'ing it to use the ABI DSO
I think to actually fix it, we need libpython3.so to be a copy of libpython3.12.so with the correct soname, e.g.:
|
The .so is useless, IMO we should delete it without replacement. It's not needed for extensions (importable modules), since those normally shouldn't link to libpython -- they're loaded by Python, which already has the correct libpython loaded. (If you link to For embedding, you can build & distribute Python with the embedding application (and then you don't need stable ABI), or try finding a “system libpython” to link to (which is tricky, but mostly possible -- but you'll end up with the versioned We can definitely improve the situation for both cases, but I don't think copying or symlinking the current IMO, a good step would be to actually limit the set of symbols |
The stable ABI is still useful IMO. Take PostgresSQL plpython for example, the extension itself doesn't need newer versions of python at compiling time. But on rhel8/Rock8, the plpython package gets stuck with the system's python3.6. To use a new version of python, the extension has to be re-complied. But it is not necessary if the |
It is possible, but I don't think it would be useful. If the python binary is built with --enable-shared, it can't be linked to libpython3.so and has to use libpython3.XX.so. Any extension module loaded by the python binary would have access to symbols loaded from the regular libpython3.XX.so even if it's linked to libpython3.so. If the python binary is statically linked with libpython (which e.g. the debian python build does even while supplying libpython.so), the symbols come from the binary itself. We could hide those symbols but only if all extension modules use the Stable ABI. A possible alternative would be to use link-map lists (a GNU extension; see (This story is a little different on macOS, btw, which is kinda halfway between Windows and ELF in how symbols are namespaced by default. IIUC our macOS build explicitly links into a flat namespace to make it work like on ELF, but by default macOS would like to know which shared library dependency symbols should come from.) |
I am trying to create a patch for this. Interestingly, I found there is a script named stable_abi.py, which was invented to do the testing about the stable ABI. But it is not called by anyone. Where should this test be executed if I want to add it as a part of the CI process? |
It's already part of a Make rule that's used in CI. Nothing to do on that front! :) |
I don't understand well what you are trying to do. You are trying to build a program and link it to Python 3.11. That's not the stable ABI. That's just a program linked to libpython. The common usage of the stable ABI is to build a C extension and then load it in Python. Please elaborate what you are trying to do. |
I think they are trying to do things like: build a program and link to ( which is not currently achievable. This makes |
I understand that the use case is to build a program and expect that it will run with any Python version available on the system. The vim text editor managed to implement this use case by targeting the stable ABI, but loading a versioned libpython. Maybe we should provide a recipe to implement such use case. In general, you should:
@sunmy2019 is correct: If someone wants to support such use case: "load any Python available on the system using libpython3.so", the constraints should be elaborated. Which Python versions would you accept? Is Python 2.7 ok? Is an alpha version of Python 3.13 ok? Is a debug build ok? Should "Python" be loaded from anywhere on the system? IMO this kind of problem should be solved outside Python itself, with a 3rd party project which would load the "appropriate" Python version. Load a Python program, load libpython, whatever which brings "Python" into the current process. I saw some funky projects which would run a separate Python process and communicate with this process with IPC! Would it be an acceptable implementation? :-) |
We see value in On RHEL, the system is shipped with a Python distribution version "frozen" for the whole lifecycle of the product:
The common component here is Details:
|
Here is a related downstream Arch bug report. Not sure if it's all the same issue, but there was definitely a bug in the Autofoo which is now fixed in 3.12.x and above. (Arch is still on 3.11.x). |
Bug report
When playing with python3 stable ABI by following code:
Linking with
libpython3.11.so
which works:Linking with
libpython3.so
, doesn't work:Actually, the
libpython3.so
doesn't contain any meaningful symbols, and the size is suspiciously small:The statement to build
libpython3.so
looks strange, I am not sure what it is trying to do:Does the above really do anything?
From https://peps.python.org/pep-0384/
The current
libpython3.so
is clearly not doing the right thing. Applications CANNOT link to it.Your environment
Checked the python3.9/3.10/3.11 from Arch's official repo, all have this problem.
Tried to build the cpython as well, the same problem.
The text was updated successfully, but these errors were encountered: