[Python-checkins] bpo-21536: On Android, C extensions are linked to libpython (GH-12989)

Victor Stinner webhook-mailer at python.org
Mon Apr 29 03:27:53 EDT 2019


https://github.com/python/cpython/commit/254b309c801f82509597e3d7d4be56885ef94c11
commit: 254b309c801f82509597e3d7d4be56885ef94c11
branch: master
author: xdegaye <xdegaye at gmail.com>
committer: Victor Stinner <vstinner at redhat.com>
date: 2019-04-29T09:27:40+02:00
summary:

 bpo-21536: On Android, C extensions are linked to libpython (GH-12989)

files:
M Doc/distutils/apiref.rst
M Doc/whatsnew/3.8.rst
M Lib/distutils/command/build_ext.py
M Makefile.pre.in
M Misc/NEWS.d/next/Build/2019-04-25-01-51-52.bpo-21536.ACQkiC.rst
M Misc/python-config.in
M Misc/python-config.sh.in
M configure
M configure.ac

diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index c3cdfc8a0a8e..1facc0408d5b 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -279,7 +279,8 @@ the full reference.
 
    .. versionchanged:: 3.8
 
-      On Unix, C extensions are no longer linked to libpython.
+      On Unix, C extensions are no longer linked to libpython except on
+      Android.
 
 
 .. class:: Distribution
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 8d94a9ff5441..8df7538f1c43 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -883,12 +883,12 @@ Changes in the Python API
 Changes in the C API
 --------------------
 
-* On Unix, C extensions are no longer linked to libpython. When Python is
-  embedded, ``libpython`` must not be loaded with ``RTLD_LOCAL``, but
-  ``RTLD_GLOBAL`` instead. Previously, using ``RTLD_LOCAL``, it was already not
-  possible to load C extensions which were not linked to ``libpython``, like C
-  extensions of the standard library built by the ``*shared*`` section of
-  ``Modules/Setup``.
+* On Unix, C extensions are no longer linked to libpython except on
+  Android. When Python is embedded, ``libpython`` must not be loaded with
+  ``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using
+  ``RTLD_LOCAL``, it was already not possible to load C extensions which were
+  not linked to ``libpython``, like C extensions of the standard library built
+  by the ``*shared*`` section of ``Modules/Setup``.
 
 * Use of ``#`` variants of formats in parsing or building value (e.g.
   :c:func:`PyArg_ParseTuple`, :c:func:`Py_BuildValue`, :c:func:`PyObject_CallFunction`,
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index 1672d02acf1f..c3b9602461f9 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -714,5 +714,20 @@ def get_libraries(self, ext):
                 # don't extend ext.libraries, it may be shared with other
                 # extensions, it is a reference to the original list
                 return ext.libraries + [pythonlib]
+        # On Android only the main executable and LD_PRELOADs are considered
+        # to be RTLD_GLOBAL, all the dependencies of the main executable
+        # remain RTLD_LOCAL and so the shared libraries must be linked with
+        # libpython when python is built with a shared python library (issue
+        # bpo-21536).
+        else:
+            from distutils.sysconfig import get_config_var
+            if get_config_var('Py_ENABLE_SHARED'):
+                # Either a native build on an Android device or the
+                # cross-compilation of Python.
+                if (hasattr(sys, 'getandroidapilevel') or
+                        ('_PYTHON_HOST_PLATFORM' in os.environ and
+                         get_config_var('ANDROID_API_LEVEL') != 0)):
+                    ldversion = get_config_var('LDVERSION')
+                    return ext.libraries + ['python' + ldversion]
 
         return ext.libraries
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 89479ee7f1a3..7f0d8d44b3d1 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -41,6 +41,7 @@ AR=		@AR@
 READELF=	@READELF@
 SOABI=		@SOABI@
 LDVERSION=	@LDVERSION@
+LIBPYTHON=	@LIBPYTHON@
 GITVERSION=	@GITVERSION@
 GITTAG=		@GITTAG@
 GITBRANCH=	@GITBRANCH@
diff --git a/Misc/NEWS.d/next/Build/2019-04-25-01-51-52.bpo-21536.ACQkiC.rst b/Misc/NEWS.d/next/Build/2019-04-25-01-51-52.bpo-21536.ACQkiC.rst
index 8cfad76ab172..59efab83265f 100644
--- a/Misc/NEWS.d/next/Build/2019-04-25-01-51-52.bpo-21536.ACQkiC.rst
+++ b/Misc/NEWS.d/next/Build/2019-04-25-01-51-52.bpo-21536.ACQkiC.rst
@@ -1,4 +1,4 @@
-On Unix, C extensions are no longer linked to libpython.
+On Unix, C extensions are no longer linked to libpython except on Android.
 
 It is now possible for a statically linked Python to load a C extension built
 using a shared library Python.
diff --git a/Misc/python-config.in b/Misc/python-config.in
index 31ad55822e55..1df30d261d8e 100644
--- a/Misc/python-config.in
+++ b/Misc/python-config.in
@@ -47,7 +47,10 @@ for opt in opt_flags:
         print(' '.join(flags))
 
     elif opt in ('--libs', '--ldflags'):
-        libs = getvar('LIBS').split() + getvar('SYSLIBS').split()
+        libpython = getvar('LIBPYTHON')
+        libs = [libpython] if libpython else []
+        libs.extend(getvar('LIBS').split() + getvar('SYSLIBS').split())
+
         # add the prefix/lib/pythonX.Y/config dir, but only if there is no
         # shared library in prefix/lib/.
         if opt == '--ldflags':
diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in
index ac1a467678e4..33991ef0c5d4 100644
--- a/Misc/python-config.sh.in
+++ b/Misc/python-config.sh.in
@@ -41,7 +41,7 @@ LIBM="@LIBM@"
 LIBC="@LIBC@"
 SYSLIBS="$LIBM $LIBC"
 ABIFLAGS="@ABIFLAGS@"
-LIBS="@LIBS@ $SYSLIBS"
+LIBS="@LIBPYTHON@ @LIBS@ $SYSLIBS"
 BASECFLAGS="@BASECFLAGS@"
 LDLIBRARY="@LDLIBRARY@"
 OPT="@OPT@"
diff --git a/configure b/configure
index 7f26fab81fe5..8d9c73d1c386 100755
--- a/configure
+++ b/configure
@@ -631,6 +631,7 @@ SRCDIRS
 THREADHEADERS
 LIBPL
 PY_ENABLE_SHARED
+LIBPYTHON
 EXT_SUFFIX
 ALT_SOABI
 SOABI
@@ -15154,6 +15155,14 @@ LDVERSION='$(VERSION)$(ABIFLAGS)'
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5
 $as_echo "$LDVERSION" >&6; }
 
+# On Android the shared libraries must be linked with libpython.
+
+if test -z "$ANDROID_API_LEVEL"; then
+  LIBPYTHON=''
+else
+  LIBPYTHON="-lpython${VERSION}${ABIFLAGS}"
+fi
+
 
 if test x$PLATFORM_TRIPLET = x; then
   LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}"
diff --git a/configure.ac b/configure.ac
index 157e9bf40679..7d2eff0d94c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4648,6 +4648,14 @@ AC_MSG_CHECKING(LDVERSION)
 LDVERSION='$(VERSION)$(ABIFLAGS)'
 AC_MSG_RESULT($LDVERSION)
 
+# On Android the shared libraries must be linked with libpython.
+AC_SUBST(LIBPYTHON)
+if test -z "$ANDROID_API_LEVEL"; then
+  LIBPYTHON=''
+else
+  LIBPYTHON="-lpython${VERSION}${ABIFLAGS}"
+fi
+
 dnl define LIBPL after ABIFLAGS and LDVERSION is defined.
 AC_SUBST(PY_ENABLE_SHARED)
 if test x$PLATFORM_TRIPLET = x; then



More information about the Python-checkins mailing list