From 8e85a7b7b83ad1cf55470817d567a3fde53e1318 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sat, 15 Sep 2018 17:15:03 +0200 Subject: [PATCH] python: only link extension modules against libpython when distutils does too. Fixes #4117 Windows requires things to be linked, on macOS distutils doesn't link by default. On Linux etc. things are not so clear, some distros like Debian patch distutils to not link, some don't. In addition the manylinux wheels spec prohibits linking against libpython and upstream is thinking about changing the default: https://bugs.python.org/issue34814 Call into distutils to figure out what distutils does and in case it doesn't link against libpython replace the passed in Python dependency with a partial one. --- mesonbuild/modules/python.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py index 9cfbd6f8c..621d104ae 100644 --- a/mesonbuild/modules/python.py +++ b/mesonbuild/modules/python.py @@ -267,6 +267,12 @@ import sys install_paths = sysconfig.get_paths(scheme='posix_prefix', vars={'base': '', 'platbase': '', 'installed_base': ''}) +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', []))) + print (json.dumps ({ 'variables': sysconfig.get_config_vars(), 'paths': sysconfig.get_paths(), @@ -274,6 +280,7 @@ print (json.dumps ({ 'version': sysconfig.get_python_version(), 'platform': sysconfig.get_platform(), 'is_pypy': '__pypy__' in sys.builtin_module_names, + 'link_libpython': links_against_libpython(), })) ''' @@ -291,6 +298,7 @@ class PythonInstallation(ExternalProgramHolder, InterpreterObject): self.version = info['version'] self.platform = info['platform'] self.is_pypy = info['is_pypy'] + self.link_libpython = info['link_libpython'] @permittedKwargs(mod_kwargs) def extension_module(self, interpreter, state, args, kwargs): @@ -304,6 +312,18 @@ class PythonInstallation(ExternalProgramHolder, InterpreterObject): kwargs['install_dir'] = os.path.join(self.platlib_install_path, subdir) + # On macOS and some Linux distros (Debian) distutils doesn't link + # extensions against libpython. We call into distutils and mirror its + # behavior. See https://github.com/mesonbuild/meson/issues/4117 + if not self.link_libpython: + new_deps = [] + for holder in mesonlib.extract_as_list(kwargs, 'dependencies'): + dep = holder.held_object + if isinstance(dep, PythonDependency): + holder = interpreter.holderify(dep.get_partial_dependency(compile_args=True)) + new_deps.append(holder) + kwargs['dependencies'] = new_deps + suffix = self.variables.get('EXT_SUFFIX') or self.variables.get('SO') or self.variables.get('.so') # msys2's python3 has "-cpython-36m.dll", we have to be clever