-
-
Notifications
You must be signed in to change notification settings - Fork 32k
gh-133312: configure: add --enable-static-libpython-for-interpreter #133313
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
base: main
Are you sure you want to change the base?
Conversation
…eter This option changes the behavior of --enable-shared to continue to build the libpython3.x.so shared library, but not use it for linking the python3 interpreter executable. Instead, the executable is linked directly against the libpython .o files as it would be with --disable-shared. There are two benefits of this change. First, libpython uses thread-local storage, which is noticeably slower when used in a loaded module instead of in the main program, because the main program can take advantage of constant offsets from the thread state pointer but loaded modules have to dynamically call a function __tls_get_addr() to potentially allocate their thread-local storage area. (There is another thread-local storage model for dynamic libraries which mitigates most of this performance hit, but it comes at the cost of preventing dlopen("libpython3.x.so"), which is a use case we want to preserve.) Second, this improves the user experience around relocatable Python a little bit, in that we don't need to use an $ORIGIN-relative path to locate libpython3.x.so, which has some mild benefits around musl (which does not support $ORIGIN-relative DT_NEEDED, only $ORIGIN-relative DT_RPATH/DT_RUNPATH), users who want to make the interpreter setuid or setcap (which prevents processing $ORIGIN), etc.
@geofft - I think you need to run |
Thanks @AA-Turner and @colesbury! Also cc @vstinner, you've made some other similar changes to configure.ac so this might be of interest to you. |
Thanks @geofft! Also of note, the only way to get this behavior currently is to perform two builds and hack them together, which is what Debian does (or used to do?). Could you speak to that a bit? (I believe you have more context than me) |
Yeah, I did a longer writeup in the issue, #133312, with some links to what Debian is currently doing. |
In this case, what's the use case for libpython? Is it to embed Python in an application? What happens if you load libpython in the |
Yes, it's for embedding use cases (gdb with Python extensions, bundlers/compilers like Nuitka that produce a binary that links libpython, the test binary produced by
How/why would you load it? Extension modules are supposed to not link libpython.so, because if they do, they will fail to load in a In other words, any Python code that loads libpython, either via ctypes etc. or via an extension module with a library dependency on libpython, will fail to work on a |
Since option name bikeshedding was requested: rather than That would reflect that the main interpreter binary isn't using the shared library, but the build process is being asked to emit the shared library anyway. Setting |
So, my hesitation here is that Therefore, doing something like If we're all relatively confident that this is okay, then I can change the patch to do that, but that is why my current approach is to add a single new option. Under this approach, |
This option changes the behavior of --enable-shared to continue to build the libpython3.x.so shared library, but not use it for linking the python3 interpreter executable. Instead, the executable is linked directly against the libpython .o files as it would be with --disable-shared.
There are two benefits of this change. First, libpython uses thread-local storage, which is noticeably slower when used in a loaded module instead of in the main program, because the main program can take advantage of constant offsets from the thread state pointer but loaded modules have to dynamically call a function __tls_get_addr() to potentially allocate their thread-local storage area. (There is another thread-local storage model for dynamic libraries which mitigates most of this performance hit, but it comes at the cost of preventing dlopen("libpython3.x.so"), which is a use case we want to preserve.)
Second, this improves the user experience around relocatable Python a little bit, in that we don't need to use an $ORIGIN-relative path to locate libpython3.x.so, which has some mild benefits around musl (which does not support $ORIGIN-relative DT_NEEDED, only $ORIGIN-relative DT_RPATH/DT_RUNPATH), users who want to make the interpreter setuid or setcap (which prevents processing $ORIGIN), etc.
📚 Documentation preview 📚: https://cpython-previews--133313.org.readthedocs.build/