Skip to content

Commit c994c8f

Browse files
embrayvstinner
authored andcommitted
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.
1 parent 438a12d commit c994c8f

File tree

6 files changed

+40
-26
lines changed

6 files changed

+40
-26
lines changed

Doc/distutils/apiref.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ the full reference.
290290
.. versionchanged:: 3.8
291291

292292
On Unix, C extensions are no longer linked to libpython except on
293-
Android.
293+
Android and Cygwin.
294294

295295

296296
.. class:: Distribution

Doc/whatsnew/3.8.rst

+9-8
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ environment variable, can be set using the new ``./configure --with-trace-refs``
138138
build option.
139139
(Contributed by Victor Stinner in :issue:`36465`.)
140140

141-
On Unix, C extensions are no longer linked to libpython except on Android.
141+
On Unix, C extensions are no longer linked to libpython except on Android
142+
and Cygwin.
142143
It is now possible
143144
for a statically linked Python to load a C extension built using a shared
144145
library Python.
@@ -163,8 +164,8 @@ previous command fails (replace ``X.Y`` with the Python version).
163164

164165
On the other hand, ``pkg-config python3.8 --libs`` no longer contains
165166
``-lpython3.8``. C extensions must not be linked to libpython (except on
166-
Android, case handled by the script); this change is backward incompatible on
167-
purpose.
167+
Android and Cygwin, whose cases are handled by the script);
168+
this change is backward incompatible on purpose.
168169
(Contributed by Victor Stinner in :issue:`36721`.)
169170

170171
f-strings now support = for quick and easy debugging
@@ -1061,12 +1062,12 @@ Changes in the C API
10611062
instead.
10621063
(Contributed by Victor Stinner in :issue:`36728`.)
10631064

1064-
* On Unix, C extensions are no longer linked to libpython except on
1065-
Android. When Python is embedded, ``libpython`` must not be loaded with
1065+
* On Unix, C extensions are no longer linked to libpython except on Android
1066+
and Cygwin. When Python is embedded, ``libpython`` must not be loaded with
10661067
``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using
1067-
``RTLD_LOCAL``, it was already not possible to load C extensions which were
1068-
not linked to ``libpython``, like C extensions of the standard library built
1069-
by the ``*shared*`` section of ``Modules/Setup``.
1068+
``RTLD_LOCAL``, it was already not possible to load C extensions which
1069+
were not linked to ``libpython``, like C extensions of the standard
1070+
library built by the ``*shared*`` section of ``Modules/Setup``.
10701071

10711072
* Use of ``#`` variants of formats in parsing or building value (e.g.
10721073
:c:func:`PyArg_ParseTuple`, :c:func:`Py_BuildValue`, :c:func:`PyObject_CallFunction`,

Lib/distutils/command/build_ext.py

+24-12
Original file line numberDiff line numberDiff line change
@@ -714,20 +714,32 @@ def get_libraries(self, ext):
714714
# don't extend ext.libraries, it may be shared with other
715715
# extensions, it is a reference to the original list
716716
return ext.libraries + [pythonlib]
717-
# On Android only the main executable and LD_PRELOADs are considered
718-
# to be RTLD_GLOBAL, all the dependencies of the main executable
719-
# remain RTLD_LOCAL and so the shared libraries must be linked with
720-
# libpython when python is built with a shared python library (issue
721-
# bpo-21536).
722717
else:
718+
# On Android only the main executable and LD_PRELOADs are considered
719+
# to be RTLD_GLOBAL, all the dependencies of the main executable
720+
# remain RTLD_LOCAL and so the shared libraries must be linked with
721+
# libpython when python is built with a shared python library (issue
722+
# bpo-21536).
723+
# On Cygwin (and if required, other POSIX-like platforms based on
724+
# Windows like MinGW) it is simply necessary that all symbols in
725+
# shared libraries are resolved at link time.
723726
from distutils.sysconfig import get_config_var
727+
link_libpython = False
724728
if get_config_var('Py_ENABLE_SHARED'):
725-
# Either a native build on an Android device or the
726-
# cross-compilation of Python.
727-
if (hasattr(sys, 'getandroidapilevel') or
728-
('_PYTHON_HOST_PLATFORM' in os.environ and
729-
get_config_var('ANDROID_API_LEVEL') != 0)):
730-
ldversion = get_config_var('LDVERSION')
731-
return ext.libraries + ['python' + ldversion]
729+
# A native build on an Android device or on Cygwin
730+
if hasattr(sys, 'getandroidapilevel'):
731+
link_libpython = True
732+
elif sys.platform == 'cygwin':
733+
link_libpython = True
734+
elif '_PYTHON_HOST_PLATFORM' in os.environ:
735+
# We are cross-compiling for one of the relevant platforms
736+
if get_config_var('ANDROID_API_LEVEL') != 0:
737+
link_libpython = True
738+
elif get_config_var('MACHDEP') == 'cygwin':
739+
link_libpython = True
740+
741+
if link_libpython:
742+
ldversion = get_config_var('LDVERSION')
743+
return ext.libraries + ['python' + ldversion]
732744

733745
return ext.libraries

Misc/NEWS.d/3.8.0a4.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,8 @@ Remove the stale scriptsinstall Makefile target.
10521052
.. nonce: ACQkiC
10531053
.. section: Build
10541054
1055-
On Unix, C extensions are no longer linked to libpython except on Android.
1055+
On Unix, C extensions are no longer linked to libpython except on Android
1056+
and Cygwin.
10561057

10571058
It is now possible for a statically linked Python to load a C extension
10581059
built using a shared library Python.

configure

+2-2
Original file line numberDiff line numberDiff line change
@@ -15129,9 +15129,9 @@ LDVERSION='$(VERSION)$(ABIFLAGS)'
1512915129
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5
1513015130
$as_echo "$LDVERSION" >&6; }
1513115131

15132-
# On Android the shared libraries must be linked with libpython.
15132+
# On Android and Cygwin the shared libraries must be linked with libpython.
1513315133

15134-
if test -z "$ANDROID_API_LEVEL"; then
15134+
if test -z "$ANDROID_API_LEVEL" -o "$MACHDEP" != "cygwin"; then
1513515135
LIBPYTHON=''
1513615136
else
1513715137
LIBPYTHON="-lpython${VERSION}${ABIFLAGS}"

configure.ac

+2-2
Original file line numberDiff line numberDiff line change
@@ -4620,9 +4620,9 @@ AC_MSG_CHECKING(LDVERSION)
46204620
LDVERSION='$(VERSION)$(ABIFLAGS)'
46214621
AC_MSG_RESULT($LDVERSION)
46224622

4623-
# On Android the shared libraries must be linked with libpython.
4623+
# On Android and Cygwin the shared libraries must be linked with libpython.
46244624
AC_SUBST(LIBPYTHON)
4625-
if test -z "$ANDROID_API_LEVEL"; then
4625+
if test -z "$ANDROID_API_LEVEL" -o "$MACHDEP" != "cygwin"; then
46264626
LIBPYTHON=''
46274627
else
46284628
LIBPYTHON="-lpython${VERSION}${ABIFLAGS}"

0 commit comments

Comments
 (0)