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

This commit is contained in:
xdegaye 2019-04-29 09:27:40 +02:00 committed by Victor Stinner
parent b021ba5028
commit 254b309c80
9 changed files with 47 additions and 10 deletions

View File

@ -279,7 +279,8 @@ the full reference.
.. versionchanged:: 3.8 .. 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 .. class:: Distribution

View File

@ -883,12 +883,12 @@ Changes in the Python API
Changes in the C API Changes in the C API
-------------------- --------------------
* On Unix, C extensions are no longer linked to libpython. When Python is * On Unix, C extensions are no longer linked to libpython except on
embedded, ``libpython`` must not be loaded with ``RTLD_LOCAL``, but Android. When Python is embedded, ``libpython`` must not be loaded with
``RTLD_GLOBAL`` instead. Previously, using ``RTLD_LOCAL``, it was already not ``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using
possible to load C extensions which were not linked to ``libpython``, like C ``RTLD_LOCAL``, it was already not possible to load C extensions which were
extensions of the standard library built by the ``*shared*`` section of not linked to ``libpython``, like C extensions of the standard library built
``Modules/Setup``. by the ``*shared*`` section of ``Modules/Setup``.
* Use of ``#`` variants of formats in parsing or building value (e.g. * Use of ``#`` variants of formats in parsing or building value (e.g.
:c:func:`PyArg_ParseTuple`, :c:func:`Py_BuildValue`, :c:func:`PyObject_CallFunction`, :c:func:`PyArg_ParseTuple`, :c:func:`Py_BuildValue`, :c:func:`PyObject_CallFunction`,

View File

@ -714,5 +714,20 @@ class build_ext(Command):
# don't extend ext.libraries, it may be shared with other # don't extend ext.libraries, it may be shared with other
# extensions, it is a reference to the original list # extensions, it is a reference to the original list
return ext.libraries + [pythonlib] 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 return ext.libraries

View File

@ -41,6 +41,7 @@ AR= @AR@
READELF= @READELF@ READELF= @READELF@
SOABI= @SOABI@ SOABI= @SOABI@
LDVERSION= @LDVERSION@ LDVERSION= @LDVERSION@
LIBPYTHON= @LIBPYTHON@
GITVERSION= @GITVERSION@ GITVERSION= @GITVERSION@
GITTAG= @GITTAG@ GITTAG= @GITTAG@
GITBRANCH= @GITBRANCH@ GITBRANCH= @GITBRANCH@

View File

@ -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 It is now possible for a statically linked Python to load a C extension built
using a shared library Python. using a shared library Python.

View File

@ -47,7 +47,10 @@ for opt in opt_flags:
print(' '.join(flags)) print(' '.join(flags))
elif opt in ('--libs', '--ldflags'): 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 # add the prefix/lib/pythonX.Y/config dir, but only if there is no
# shared library in prefix/lib/. # shared library in prefix/lib/.
if opt == '--ldflags': if opt == '--ldflags':

View File

@ -41,7 +41,7 @@ LIBM="@LIBM@"
LIBC="@LIBC@" LIBC="@LIBC@"
SYSLIBS="$LIBM $LIBC" SYSLIBS="$LIBM $LIBC"
ABIFLAGS="@ABIFLAGS@" ABIFLAGS="@ABIFLAGS@"
LIBS="@LIBS@ $SYSLIBS" LIBS="@LIBPYTHON@ @LIBS@ $SYSLIBS"
BASECFLAGS="@BASECFLAGS@" BASECFLAGS="@BASECFLAGS@"
LDLIBRARY="@LDLIBRARY@" LDLIBRARY="@LDLIBRARY@"
OPT="@OPT@" OPT="@OPT@"

9
configure vendored
View File

@ -631,6 +631,7 @@ SRCDIRS
THREADHEADERS THREADHEADERS
LIBPL LIBPL
PY_ENABLE_SHARED PY_ENABLE_SHARED
LIBPYTHON
EXT_SUFFIX EXT_SUFFIX
ALT_SOABI ALT_SOABI
SOABI SOABI
@ -15154,6 +15155,14 @@ LDVERSION='$(VERSION)$(ABIFLAGS)'
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5
$as_echo "$LDVERSION" >&6; } $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 if test x$PLATFORM_TRIPLET = x; then
LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}" LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}"

View File

@ -4648,6 +4648,14 @@ AC_MSG_CHECKING(LDVERSION)
LDVERSION='$(VERSION)$(ABIFLAGS)' LDVERSION='$(VERSION)$(ABIFLAGS)'
AC_MSG_RESULT($LDVERSION) 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. dnl define LIBPL after ABIFLAGS and LDVERSION is defined.
AC_SUBST(PY_ENABLE_SHARED) AC_SUBST(PY_ENABLE_SHARED)
if test x$PLATFORM_TRIPLET = x; then if test x$PLATFORM_TRIPLET = x; then