https://github.com/python/cpython/commit/c88c27b0c1c09c125fe6a5ad78a4d42cf9c3fcd2
commit: c88c27b0c1c09c125fe6a5ad78a4d42cf9c3fcd2
branch: main
author: Geoffrey Thomas <[email protected]>
committer: pablogsal <[email protected]>
date: 2026-04-14T16:26:19+01:00
summary:
gh-133312: configure: add --enable-static-libpython-for-interpreter (#133313)
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.
files:
A Misc/NEWS.d/next/Build/2025-05-02-17-06-10.gh-issue-133312.YkO6BI.rst
M Doc/using/configure.rst
M configure
M configure.ac
diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst
index bf25de7cc90c6c0..d5c17560b6658a6 100644
--- a/Doc/using/configure.rst
+++ b/Doc/using/configure.rst
@@ -1012,6 +1012,21 @@ Linker options
.. versionadded:: 3.10
+.. option:: --enable-static-libpython-for-interpreter
+
+ Do not link the Python interpreter binary (``python3``) against the
+ shared Python library; instead, statically link the interpreter
+ against ``libpython`` as if ``--enable-shared`` had not been used,
+ but continue to build the shared ``libpython`` (for use by other
+ programs).
+
+ This option does nothing if ``--enable-shared`` is not used.
+
+ The default (when ``-enable-shared`` is used) is to link the Python
+ interpreter against the built shared library.
+
+ .. versionadded:: next
+
Libraries options
-----------------
diff --git
a/Misc/NEWS.d/next/Build/2025-05-02-17-06-10.gh-issue-133312.YkO6BI.rst
b/Misc/NEWS.d/next/Build/2025-05-02-17-06-10.gh-issue-133312.YkO6BI.rst
new file mode 100644
index 000000000000000..3ad2db63907ecbf
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2025-05-02-17-06-10.gh-issue-133312.YkO6BI.rst
@@ -0,0 +1,8 @@
+Add a new ``./configure`` option
+:option:`--enable-static-libpython-for-interpreter` which, when used
+with :option:`--enable-shared`, continues to build the shared library
+but does not use it for the interpreter. Instead, libpython is
+statically linked into the interpreter, as if :option:`--enable-shared`
+had not been used. This allows you to do a single build and get a Python
+interpreter binary that does not use a shared library but also get a
+shared library for use by other programs.
diff --git a/configure b/configure
index 07c16a4e37874e4..8620eb3fbdd36be 100755
--- a/configure
+++ b/configure
@@ -1100,6 +1100,7 @@ enable_wasm_pthreads
with_suffix
enable_shared
with_static_libpython
+enable_static_libpython_for_interpreter
enable_profiling
enable_gil
with_pydebug
@@ -1837,6 +1838,10 @@ Optional Features:
no)
--enable-shared enable building a shared Python library (default is
no)
+ --enable-static-libpython-for-interpreter
+ even with --enable-shared, statically link libpython
+ into the interpreter (default is to use the shared
+ library)
--enable-profiling enable C-level code profiling with gprof (default is
no)
--disable-gil enable support for running without the GIL (default
@@ -7688,6 +7693,22 @@ fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for
--enable-static-libpython-for-interpreter" >&5
+printf %s "checking for --enable-static-libpython-for-interpreter... " >&6; }
+# Check whether --enable-static-libpython-for-interpreter was given.
+if test ${enable_static_libpython_for_interpreter+y}
+then :
+ enableval=$enable_static_libpython_for_interpreter;
+fi
+
+
+if test -z "$enable_static_libpython_for_interpreter"
+then
+ enable_static_libpython_for_interpreter="no"
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:
$enable_static_libpython_for_interpreter" >&5
+printf "%s\n" "$enable_static_libpython_for_interpreter" >&6; }
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-profiling"
>&5
printf %s "checking for --enable-profiling... " >&6; }
# Check whether --enable-profiling was given.
@@ -7977,7 +7998,11 @@ if test "$PY_ENABLE_SHARED" = 1 || test
"$enable_framework" ; then
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
fi
# Link Python program to the shared library
- LINK_PYTHON_OBJS='$(BLDLIBRARY)'
+ if test "$enable_static_libpython_for_interpreter" = "yes"; then
+ LINK_PYTHON_OBJS='$(LIBRARY_OBJS)'
+ else
+ LINK_PYTHON_OBJS='$(BLDLIBRARY)'
+ fi
else
if test "$STATIC_LIBPYTHON" = 0; then
# Build Python needs object files but don't need to build
@@ -9473,7 +9498,12 @@ BOLT_BINARIES='$(BUILDPYTHON)'
if test "x$enable_shared" = xyes
then :
- BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)"
+ if test "x$enable_static_libpython_for_interpreter" = xno
+then :
+
+ BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)"
+
+fi
fi
diff --git a/configure.ac b/configure.ac
index d6e152d42b765e2..d73b37327fe5849 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1526,6 +1526,17 @@ fi],
[AC_MSG_RESULT([yes])])
AC_SUBST([STATIC_LIBPYTHON])
+AC_MSG_CHECKING([for --enable-static-libpython-for-interpreter])
+AC_ARG_ENABLE([static-libpython-for-interpreter],
+ AS_HELP_STRING([--enable-static-libpython-for-interpreter],
+ [even with --enable-shared, statically link libpython into
the interpreter (default is to use the shared library)]))
+
+if test -z "$enable_static_libpython_for_interpreter"
+then
+ enable_static_libpython_for_interpreter="no"
+fi
+AC_MSG_RESULT([$enable_static_libpython_for_interpreter])
+
AC_MSG_CHECKING([for --enable-profiling])
AC_ARG_ENABLE([profiling],
AS_HELP_STRING([--enable-profiling], [enable C-level code
profiling with gprof (default is no)]))
@@ -1679,7 +1690,11 @@ if test "$PY_ENABLE_SHARED" = 1 || test
"$enable_framework" ; then
LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS"
fi
# Link Python program to the shared library
- LINK_PYTHON_OBJS='$(BLDLIBRARY)'
+ if test "$enable_static_libpython_for_interpreter" = "yes"; then
+ LINK_PYTHON_OBJS='$(LIBRARY_OBJS)'
+ else
+ LINK_PYTHON_OBJS='$(BLDLIBRARY)'
+ fi
else
if test "$STATIC_LIBPYTHON" = 0; then
# Build Python needs object files but don't need to build
@@ -2161,11 +2176,14 @@ if test "$Py_BOLT" = 'true' ; then
fi
fi
-dnl Enable BOLT of libpython if built.
+dnl Enable BOLT of libpython if built and used by the python3 binary.
+dnl (If it is built but not used, we cannot profile it.)
AC_SUBST([BOLT_BINARIES])
BOLT_BINARIES='$(BUILDPYTHON)'
AS_VAR_IF([enable_shared], [yes], [
- BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)"
+ AS_VAR_IF([enable_static_libpython_for_interpreter], [no], [
+ BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)"
+ ])
])
AC_ARG_VAR(
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]