python module: make it work with pypy
pypy installations don't usuallyy ship with pkg-config files, we thus need to replicate what their version of distutils does. In addition, we also try our best to build against other pythons that do not have pkg-config files.
This commit is contained in:
parent
6c115f1626
commit
8bda86faab
|
@ -62,7 +62,7 @@ class PythonDependency(ExternalDependency):
|
|||
else:
|
||||
self.major_version = 2
|
||||
|
||||
if DependencyMethods.PKGCONFIG in self.methods:
|
||||
if DependencyMethods.PKGCONFIG in self.methods and not python_holder.is_pypy:
|
||||
pkg_version = self.variables.get('LDVERSION') or self.version
|
||||
pkg_libdir = self.variables.get('LIBPC')
|
||||
old_pkg_libdir = os.environ.get('PKG_CONFIG_LIBDIR')
|
||||
|
@ -94,14 +94,46 @@ class PythonDependency(ExternalDependency):
|
|||
else:
|
||||
self.pkgdep = None
|
||||
|
||||
if mesonlib.is_windows() and DependencyMethods.SYSCONFIG in self.methods:
|
||||
if DependencyMethods.SYSCONFIG in self.methods:
|
||||
if mesonlib.is_windows():
|
||||
self._find_libpy_windows(environment)
|
||||
else:
|
||||
self._find_libpy(python_holder, environment)
|
||||
|
||||
if self.is_found:
|
||||
mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.green('YES'))
|
||||
else:
|
||||
mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.red('NO'))
|
||||
|
||||
def _find_libpy(self, python_holder, environment):
|
||||
if python_holder.is_pypy:
|
||||
if self.major_version == 3:
|
||||
libname = 'pypy3-c'
|
||||
else:
|
||||
libname = 'pypy-c'
|
||||
libdir = os.path.join(self.variables.get('base'), 'bin')
|
||||
libdirs = [libdir]
|
||||
else:
|
||||
libname = 'python{}'.format(self.version)
|
||||
if 'DEBUG_EXT' in self.variables:
|
||||
libname += self.variables['DEBUG_EXT']
|
||||
if 'ABIFLAGS' in self.variables:
|
||||
libname += self.variables['ABIFLAGS']
|
||||
libdirs = []
|
||||
|
||||
largs = self.compiler.find_library(libname, environment, libdirs)
|
||||
|
||||
self.is_found = largs is not None
|
||||
|
||||
self.link_args = largs
|
||||
|
||||
inc_paths = mesonlib.OrderedSet([
|
||||
self.variables.get('INCLUDEPY'),
|
||||
self.paths.get('include'),
|
||||
self.paths.get('platinclude')])
|
||||
|
||||
self.compile_args += ['-I' + path for path in inc_paths if path]
|
||||
|
||||
def get_windows_python_arch(self):
|
||||
if self.platform == 'mingw':
|
||||
pycc = self.variables.get('CC')
|
||||
|
@ -192,7 +224,7 @@ class PythonDependency(ExternalDependency):
|
|||
elif mesonlib.is_osx():
|
||||
return [DependencyMethods.PKGCONFIG, DependencyMethods.EXTRAFRAMEWORK]
|
||||
else:
|
||||
return [DependencyMethods.PKGCONFIG]
|
||||
return [DependencyMethods.PKGCONFIG, DependencyMethods.SYSCONFIG]
|
||||
|
||||
def get_pkgconfig_variable(self, variable_name, kwargs):
|
||||
if self.pkgdep:
|
||||
|
@ -225,6 +257,14 @@ print (json.dumps(sysconfig.get_paths(scheme='posix_prefix', vars={'base': '', '
|
|||
'''
|
||||
|
||||
|
||||
IS_PYPY_COMMAND = '''
|
||||
import sys
|
||||
import json
|
||||
|
||||
print (json.dumps('__pypy__' in sys.builtin_module_names))
|
||||
'''
|
||||
|
||||
|
||||
class PythonInstallation(ExternalProgramHolder, InterpreterObject):
|
||||
def __init__(self, interpreter, python):
|
||||
InterpreterObject.__init__(self)
|
||||
|
@ -238,6 +278,7 @@ class PythonInstallation(ExternalProgramHolder, InterpreterObject):
|
|||
self.purelib_install_path = os.path.join(prefix, install_paths['purelib'][1:])
|
||||
self.version = run_command(python, "import sysconfig; print (sysconfig.get_python_version())")
|
||||
self.platform = run_command(python, "import sysconfig; print (sysconfig.get_platform())")
|
||||
self.is_pypy = json.loads(run_command(python, IS_PYPY_COMMAND))
|
||||
|
||||
@permittedSnippetKwargs(mod_kwargs)
|
||||
def extension_module(self, interpreter, state, args, kwargs):
|
||||
|
@ -449,6 +490,8 @@ class PythonModule(ExtensionModule):
|
|||
version = run_command(python, "import sysconfig; print (sysconfig.get_python_version())")
|
||||
if not version:
|
||||
res = ExternalProgramHolder(NonExistingExternalProgram())
|
||||
if required:
|
||||
raise mesonlib.MesonException('{} is not a valid python'.format(python))
|
||||
else:
|
||||
res = PythonInstallation(interpreter, python)
|
||||
|
||||
|
|
|
@ -3186,6 +3186,19 @@ class PythonTests(BasePlatformTests):
|
|||
|
||||
self.wipe()
|
||||
|
||||
for py in ('pypy', 'pypy3'):
|
||||
try:
|
||||
self.init(testdir, ['-Dpython=%s' % py])
|
||||
except unittest.SkipTest:
|
||||
# Same as above, pypy2 and pypy3 are not expected to be present
|
||||
# on the test system, the test project only raises in these cases
|
||||
continue
|
||||
|
||||
# We have a pypy, this is expected to work
|
||||
self.build()
|
||||
self.run_tests()
|
||||
self.wipe()
|
||||
|
||||
# The test is configured to error out with MESON_SKIP_TEST
|
||||
# in case it could not find python
|
||||
with self.assertRaises(unittest.SkipTest):
|
||||
|
|
Loading…
Reference in New Issue