bpo-21536: On Cygwin, C extensions must be linked with libpython (GH-13549)

It is also possible to link against a library or executable with a
statically linked libpython, but not both with the same DLL.  In fact
building a statically linked python is currently broken on Cygwin
for other (related) reasons.

The same problem applies to other POSIX-like layers over Windows
(MinGW, MSYS) but Python's build system does not seem to attempt
to support those platforms at the moment.
This commit is contained in:
E. M. Bray 2019-05-24 17:33:47 +02:00 committed by Victor Stinner
parent 438a12dd9d
commit c994c8fc19
6 changed files with 40 additions and 26 deletions

View file

@ -290,7 +290,7 @@ the full reference.
.. versionchanged:: 3.8 .. versionchanged:: 3.8
On Unix, C extensions are no longer linked to libpython except on On Unix, C extensions are no longer linked to libpython except on
Android. Android and Cygwin.
.. class:: Distribution .. class:: Distribution

View file

@ -138,7 +138,8 @@ environment variable, can be set using the new ``./configure --with-trace-refs``
build option. build option.
(Contributed by Victor Stinner in :issue:`36465`.) (Contributed by Victor Stinner in :issue:`36465`.)
On Unix, C extensions are no longer linked to libpython except on Android. On Unix, C extensions are no longer linked to libpython except on Android
and Cygwin.
It is now possible It is now possible
for a statically linked Python to load a C extension built using a shared for a statically linked Python to load a C extension built using a shared
library Python. library Python.
@ -163,8 +164,8 @@ previous command fails (replace ``X.Y`` with the Python version).
On the other hand, ``pkg-config python3.8 --libs`` no longer contains On the other hand, ``pkg-config python3.8 --libs`` no longer contains
``-lpython3.8``. C extensions must not be linked to libpython (except on ``-lpython3.8``. C extensions must not be linked to libpython (except on
Android, case handled by the script); this change is backward incompatible on Android and Cygwin, whose cases are handled by the script);
purpose. this change is backward incompatible on purpose.
(Contributed by Victor Stinner in :issue:`36721`.) (Contributed by Victor Stinner in :issue:`36721`.)
f-strings now support = for quick and easy debugging f-strings now support = for quick and easy debugging
@ -1061,12 +1062,12 @@ Changes in the C API
instead. instead.
(Contributed by Victor Stinner in :issue:`36728`.) (Contributed by Victor Stinner in :issue:`36728`.)
* On Unix, C extensions are no longer linked to libpython except on * On Unix, C extensions are no longer linked to libpython except on Android
Android. When Python is embedded, ``libpython`` must not be loaded with and Cygwin. When Python is embedded, ``libpython`` must not be loaded with
``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using ``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using
``RTLD_LOCAL``, it was already not possible to load C extensions which were ``RTLD_LOCAL``, it was already not possible to load C extensions which
not linked to ``libpython``, like C extensions of the standard library built were not linked to ``libpython``, like C extensions of the standard
by the ``*shared*`` section of ``Modules/Setup``. library built 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,20 +714,32 @@ def get_libraries(self, ext):
# 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: else:
# 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).
# On Cygwin (and if required, other POSIX-like platforms based on
# Windows like MinGW) it is simply necessary that all symbols in
# shared libraries are resolved at link time.
from distutils.sysconfig import get_config_var from distutils.sysconfig import get_config_var
link_libpython = False
if get_config_var('Py_ENABLE_SHARED'): if get_config_var('Py_ENABLE_SHARED'):
# Either a native build on an Android device or the # A native build on an Android device or on Cygwin
# cross-compilation of Python. if hasattr(sys, 'getandroidapilevel'):
if (hasattr(sys, 'getandroidapilevel') or link_libpython = True
('_PYTHON_HOST_PLATFORM' in os.environ and elif sys.platform == 'cygwin':
get_config_var('ANDROID_API_LEVEL') != 0)): link_libpython = True
ldversion = get_config_var('LDVERSION') elif '_PYTHON_HOST_PLATFORM' in os.environ:
return ext.libraries + ['python' + ldversion] # We are cross-compiling for one of the relevant platforms
if get_config_var('ANDROID_API_LEVEL') != 0:
link_libpython = True
elif get_config_var('MACHDEP') == 'cygwin':
link_libpython = True
if link_libpython:
ldversion = get_config_var('LDVERSION')
return ext.libraries + ['python' + ldversion]
return ext.libraries return ext.libraries

View file

@ -1052,7 +1052,8 @@ Remove the stale scriptsinstall Makefile target.
.. nonce: ACQkiC .. nonce: ACQkiC
.. section: Build .. section: Build
On Unix, C extensions are no longer linked to libpython except on Android. On Unix, C extensions are no longer linked to libpython except on Android
and Cygwin.
It is now possible for a statically linked Python to load a C extension It is now possible for a statically linked Python to load a C extension
built using a shared library Python. built using a shared library Python.

4
configure vendored
View file

@ -15129,9 +15129,9 @@ 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. # On Android and Cygwin the shared libraries must be linked with libpython.
if test -z "$ANDROID_API_LEVEL"; then if test -z "$ANDROID_API_LEVEL" -o "$MACHDEP" != "cygwin"; then
LIBPYTHON='' LIBPYTHON=''
else else
LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" LIBPYTHON="-lpython${VERSION}${ABIFLAGS}"

View file

@ -4620,9 +4620,9 @@ 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. # On Android and Cygwin the shared libraries must be linked with libpython.
AC_SUBST(LIBPYTHON) AC_SUBST(LIBPYTHON)
if test -z "$ANDROID_API_LEVEL"; then if test -z "$ANDROID_API_LEVEL" -o "$MACHDEP" != "cygwin"; then
LIBPYTHON='' LIBPYTHON=''
else else
LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" LIBPYTHON="-lpython${VERSION}${ABIFLAGS}"