Make LLVMDependency a ConfigToolDependency

pull/2512/head
Dylan Baker 7 years ago
parent cda0e33650
commit f0248b0342
  1. 7
      mesonbuild/dependencies/base.py
  2. 105
      mesonbuild/dependencies/dev.py

@ -247,11 +247,12 @@ class ConfigToolDependency(ExternalDependency):
return True return True
def get_config_value(self, args, stage): def get_config_value(self, args, stage):
p, out, _ = Popen_safe([self.config] + args) p, out, err = Popen_safe([self.config] + args)
if p.returncode != 0: if p.returncode != 0:
if self.required: if self.required:
raise DependencyException('Could not generate {} for {}'.format( raise DependencyException(
stage, self.name)) 'Could not generate {} for {}.\n{}'.format(
stage, self.name, err))
return [] return []
return shlex.split(out) return shlex.split(out)

@ -17,14 +17,16 @@
import os import os
import re import re
import shlex
import shutil import shutil
from .. import mlog from .. import mlog
from .. import mesonlib from .. import mesonlib
from ..mesonlib import version_compare, Popen_safe, stringlistify, extract_as_list from ..mesonlib import version_compare, Popen_safe, stringlistify, extract_as_list
from .base import DependencyException, ExternalDependency, PkgConfigDependency from .base import (
from .base import strip_system_libdirs DependencyException, ExternalDependency, PkgConfigDependency,
strip_system_libdirs, ConfigToolDependency,
)
class GTestDependency(ExternalDependency): class GTestDependency(ExternalDependency):
def __init__(self, environment, kwargs): def __init__(self, environment, kwargs):
@ -109,7 +111,7 @@ class GMockDependency(ExternalDependency):
self.is_found = False self.is_found = False
class LLVMDependency(ExternalDependency): class LLVMDependency(ConfigToolDependency):
""" """
LLVM uses a special tool, llvm-config, which has arguments for getting LLVM uses a special tool, llvm-config, which has arguments for getting
c args, cxx args, and ldargs as well as version. c args, cxx args, and ldargs as well as version.
@ -121,7 +123,7 @@ class LLVMDependency(ExternalDependency):
# not be moved to the beginning of the list. The only difference between # not be moved to the beginning of the list. The only difference between
# llvm-config-6.0 and llvm-config-devel is that the former is used by # llvm-config-6.0 and llvm-config-devel is that the former is used by
# Debian and the latter is used by FreeBSD. # Debian and the latter is used by FreeBSD.
llvm_config_bins = [ tools = [
'llvm-config', # base 'llvm-config', # base
'llvm-config-5.0', 'llvm-config50', # latest stable release 'llvm-config-5.0', 'llvm-config50', # latest stable release
'llvm-config-4.0', 'llvm-config40', # old stable releases 'llvm-config-4.0', 'llvm-config40', # old stable releases
@ -132,61 +134,31 @@ class LLVMDependency(ExternalDependency):
'llvm-config-3.5', 'llvm-config35', 'llvm-config-3.5', 'llvm-config35',
'llvm-config-6.0', 'llvm-config-devel', # development snapshot 'llvm-config-6.0', 'llvm-config-devel', # development snapshot
] ]
tool_name = 'llvm-config'
__cpp_blacklist = {'-DNDEBUG'} __cpp_blacklist = {'-DNDEBUG'}
def __init__(self, environment, kwargs): def __init__(self, environment, kwargs):
# It's necessary for LLVM <= 3.8 to use the C++ linker. For 3.9 and 4.0 # It's necessary for LLVM <= 3.8 to use the C++ linker. For 3.9 and 4.0
# the C linker works fine if only using the C API. # the C linker works fine if only using the C API.
super().__init__('llvm-config', environment, 'cpp', kwargs) super().__init__('config-tool', environment, 'cpp', kwargs)
self.provided_modules = [] self.provided_modules = []
self.required_modules = set() self.required_modules = set()
self.llvmconfig = None if not self.is_found:
self.static = kwargs.get('static', False)
self.__best_found = None
# FIXME: Support multiple version requirements ala PkgConfigDependency
req_version = kwargs.get('version', None)
self.check_llvmconfig(req_version)
if self.llvmconfig is None:
if self.__best_found is not None:
mlog.log('found {!r} but need:'.format(self.__best_found),
req_version)
else:
mlog.log("No llvm-config found; can't detect dependency")
mlog.log('Dependency LLVM found:', mlog.red('NO'))
if self.required:
raise DependencyException('Dependency LLVM not found')
return
p, out, err = Popen_safe([self.llvmconfig, '--version'])
if p.returncode != 0:
mlog.debug('stdout: {}\nstderr: {}'.format(out, err))
if self.required:
raise DependencyException('Dependency LLVM not found')
mlog.log('Dependency LLVM found:', mlog.red('NO'))
return return
self.static = kwargs.get('static', False)
mlog.log('Dependency LLVM found:', mlog.green('YES'))
self.is_found = True
# Currently meson doesn't really atempt to handle pre-release versions, # Currently meson doesn't really atempt to handle pre-release versions,
# so strip the 'svn' off the end, since it will probably cuase problems # so strip the 'svn' off the end, since it will probably cuase problems
# for users who want the patch version. # for users who want the patch version.
self.version = out.strip().rstrip('svn') self.version = self.version.rstrip('svn')
p, out, err = Popen_safe([self.llvmconfig, '--components'])
if p.returncode != 0:
raise DependencyException('Could not generate modules for LLVM:\n' + err)
self.provided_modules = shlex.split(out)
self.provided_modules = self.get_config_value(['--components'], 'modules')
modules = stringlistify(extract_as_list(kwargs, 'modules')) modules = stringlistify(extract_as_list(kwargs, 'modules'))
self.check_components(modules) self.check_components(modules)
opt_modules = stringlistify(extract_as_list(kwargs, 'optional_modules')) opt_modules = stringlistify(extract_as_list(kwargs, 'optional_modules'))
self.check_components(opt_modules, required=False) self.check_components(opt_modules, required=False)
p, out, err = Popen_safe([self.llvmconfig, '--cppflags']) cargs = set(self.get_config_value(['--cppflags'], 'compile_args'))
if p.returncode != 0:
raise DependencyException('Could not generate includedir for LLVM:\n' + err)
cargs = mesonlib.OrderedSet(shlex.split(out))
self.compile_args = list(cargs.difference(self.__cpp_blacklist)) self.compile_args = list(cargs.difference(self.__cpp_blacklist))
if version_compare(self.version, '>= 3.9'): if version_compare(self.version, '>= 3.9'):
@ -198,11 +170,9 @@ class LLVMDependency(ExternalDependency):
def _set_new_link_args(self): def _set_new_link_args(self):
"""How to set linker args for LLVM versions >= 3.9""" """How to set linker args for LLVM versions >= 3.9"""
link_args = ['--link-static', '--system-libs'] if self.static else ['--link-shared'] link_args = ['--link-static', '--system-libs'] if self.static else ['--link-shared']
p, out, err = Popen_safe( self.link_args = self.get_config_value(
[self.llvmconfig, '--libs', '--ldflags'] + link_args + list(self.required_modules)) ['--libs', '--ldflags'] + link_args + list(self.required_modules),
if p.returncode != 0: 'link_args')
raise DependencyException('Could not generate libs for LLVM:\n' + err)
self.link_args = shlex.split(out)
def _set_old_link_args(self): def _set_old_link_args(self):
"""Setting linker args for older versions of llvm. """Setting linker args for older versions of llvm.
@ -213,20 +183,15 @@ class LLVMDependency(ExternalDependency):
of course we do. of course we do.
""" """
if self.static: if self.static:
p, out, err = Popen_safe( self.link_args = self.get_config_value(
[self.llvmconfig, '--libs', '--ldflags', '--system-libs'] + list(self.required_modules)) ['--libs', '--ldflags', '--system-libs'] + list(self.required_modules),
if p.returncode != 0: 'link_args')
raise DependencyException('Could not generate libs for LLVM:\n' + err)
self.link_args = shlex.split(out)
else: else:
# llvm-config will provide arguments for static linking, so we get # llvm-config will provide arguments for static linking, so we get
# to figure out for ourselves what to link with. We'll do that by # to figure out for ourselves what to link with. We'll do that by
# checking in the directory provided by --libdir for a library # checking in the directory provided by --libdir for a library
# called libLLVM-<ver>.(so|dylib|dll) # called libLLVM-<ver>.(so|dylib|dll)
p, out, err = Popen_safe([self.llvmconfig, '--libdir']) libdir = self.get_config_value(['--libdir'], 'link_args')[0]
if p.returncode != 0:
raise DependencyException('Could not generate libs for LLVM:\n' + err)
libdir = out.strip()
expected_name = 'libLLVM-{}'.format(self.version) expected_name = 'libLLVM-{}'.format(self.version)
re_name = re.compile(r'{}.(so|dll|dylib)'.format(expected_name)) re_name = re.compile(r'{}.(so|dll|dylib)'.format(expected_name))
@ -259,34 +224,6 @@ class LLVMDependency(ExternalDependency):
self.required_modules.add(mod) self.required_modules.add(mod)
mlog.log('LLVM module', mod, 'found:', mlog.green('YES')) mlog.log('LLVM module', mod, 'found:', mlog.green('YES'))
def check_llvmconfig(self, version_req):
"""Try to find the highest version of llvm-config."""
for llvmconfig in self.llvm_config_bins:
try:
p, out = Popen_safe([llvmconfig, '--version'])[0:2]
out = out.strip()
if p.returncode != 0:
continue
if version_req:
if version_compare(out, version_req, strict=True):
if self.__best_found and version_compare(
out, '<={}'.format(self.__best_found), strict=True):
continue
self.__best_found = out
self.llvmconfig = llvmconfig
else:
# If no specific version is requested use the first version
# found, since that should be the best.
self.__best_found = out
self.llvmconfig = llvmconfig
break
except (FileNotFoundError, PermissionError):
pass
if self.__best_found:
mlog.log('Found llvm-config:',
mlog.bold(shutil.which(self.llvmconfig)),
'({})'.format(out.strip()))
def need_threads(self): def need_threads(self):
return True return True

Loading…
Cancel
Save