Skip to content

Commit

Permalink
python module: stop using distutils "link to libpython" probe on rece…
Browse files Browse the repository at this point in the history
…nt python

On python >=3.8, this information is expected to be encoded in the
sysconfig vars.

In distutils, it is always necessary to link to libpython on Windows;
for posix platforms, it depends on the value of LIBPYTHON (which is the
library to link to, possibly the empty string) as generated by
configure.ac and embedded into python.pc and python-config.sh, and then
coded a second time in the distutils python sources.

There are a couple of caveats which have ramifications for Cygwin and
Android:

- python.pc and python-config.sh disagree with distutils when python is
  not built shared. In that case, the former act the same as a shared
  build, while the latter *never* links to libpython

- python.pc disagrees with python-config.sh and distutils when python is
  built shared. The former never links to libpython, while the latter do

The disagreement is resolved in favor of distutils' behavior in all
cases, and python.pc is correct for our purposes on python 3.12; see:
python/cpython#100356
python/cpython#100967

Although it was not backported to older releases, Cygwin at least has
always patched in a fix for python.pc, which behavior is now declared
canonical. We can reliably assume it is always correct.

This is the other half of the fix for #7702
  • Loading branch information
eli-schwartz authored and nirbheek committed Oct 17, 2023
1 parent d573c8f commit 3c3caf5
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions mesonbuild/scripts/python_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,23 @@ def get_install_paths():
paths, install_paths = get_install_paths()

def links_against_libpython():
from distutils.core import Distribution, Extension
cmd = Distribution().get_command_obj('build_ext')
cmd.ensure_finalized()
return bool(cmd.get_libraries(Extension('dummy', [])))
# on versions supporting python-embed.pc, this is the non-embed lib
#
# PyPy is not yet up to 3.12 and work is still pending to export the
# relevant information (it doesn't automatically provide arbitrary
# Makefile vars)
if sys.version_info >= (3, 8) and not is_pypy:
variables = sysconfig.get_config_vars()
return bool(variables.get('LIBPYTHON', 'yes'))
else:
from distutils.core import Distribution, Extension
cmd = Distribution().get_command_obj('build_ext')
cmd.ensure_finalized()
return bool(cmd.get_libraries(Extension('dummy', [])))

variables = sysconfig.get_config_vars()
variables.update({'base_prefix': getattr(sys, 'base_prefix', sys.prefix)})
is_pypy = '__pypy__' in sys.builtin_module_names

if sys.version_info < (3, 0):
suffix = variables.get('SO')
Expand All @@ -88,7 +98,7 @@ def links_against_libpython():
'install_paths': install_paths,
'version': sysconfig.get_python_version(),
'platform': sysconfig.get_platform(),
'is_pypy': '__pypy__' in sys.builtin_module_names,
'is_pypy': is_pypy,
'is_venv': sys.prefix != variables['base_prefix'],
'link_libpython': links_against_libpython(),
'suffix': suffix,
Expand Down

0 comments on commit 3c3caf5

Please sign in to comment.