|
|
|
@ -129,9 +129,6 @@ class LLVMDependency(ExternalDependency): |
|
|
|
|
'llvm-config-3.5', 'llvm-config35', |
|
|
|
|
'llvm-config-5.0', 'llvm-config-devel', # development snapshot |
|
|
|
|
] |
|
|
|
|
llvmconfig = None |
|
|
|
|
_llvmconfig_found = False |
|
|
|
|
__best_found = None |
|
|
|
|
__cpp_blacklist = {'-DNDEBUG'} |
|
|
|
|
|
|
|
|
|
def __init__(self, environment, kwargs): |
|
|
|
@ -139,11 +136,12 @@ class LLVMDependency(ExternalDependency): |
|
|
|
|
# the C linker works fine if only using the C API. |
|
|
|
|
super().__init__('llvm-config', environment, 'cpp', kwargs) |
|
|
|
|
self.modules = [] |
|
|
|
|
self.llvmconfig = None |
|
|
|
|
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: |
|
|
|
|
self.check_llvmconfig(req_version) |
|
|
|
|
if not self._llvmconfig_found: |
|
|
|
|
if self.__best_found is not None: |
|
|
|
|
mlog.log('found {!r} but need:'.format(self.__best_found), |
|
|
|
|
req_version) |
|
|
|
@ -159,31 +157,36 @@ class LLVMDependency(ExternalDependency): |
|
|
|
|
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 |
|
|
|
|
else: |
|
|
|
|
self.version = out.strip() |
|
|
|
|
mlog.log('Dependency LLVM found:', mlog.green('YES')) |
|
|
|
|
self.is_found = True |
|
|
|
|
|
|
|
|
|
p, out = Popen_safe( |
|
|
|
|
[self.llvmconfig, '--libs', '--ldflags', '--system-libs'])[:2] |
|
|
|
|
if p.returncode != 0: |
|
|
|
|
raise DependencyException('Could not generate libs for LLVM.') |
|
|
|
|
self.link_args = shlex.split(out) |
|
|
|
|
|
|
|
|
|
p, out = Popen_safe([self.llvmconfig, '--cppflags'])[:2] |
|
|
|
|
if p.returncode != 0: |
|
|
|
|
raise DependencyException('Could not generate includedir for LLVM.') |
|
|
|
|
cargs = mesonlib.OrderedSet(shlex.split(out)) |
|
|
|
|
self.compile_args = list(cargs.difference(self.__cpp_blacklist)) |
|
|
|
|
|
|
|
|
|
p, out = Popen_safe([self.llvmconfig, '--components'])[:2] |
|
|
|
|
if p.returncode != 0: |
|
|
|
|
raise DependencyException('Could not generate modules for LLVM.') |
|
|
|
|
self.modules = shlex.split(out) |
|
|
|
|
|
|
|
|
|
modules = mesonlib.stringlistify(kwargs.get('modules', [])) |
|
|
|
|
for mod in modules: |
|
|
|
|
mlog.log('Dependency LLVM found:', mlog.green('YES')) |
|
|
|
|
self.is_found = True |
|
|
|
|
|
|
|
|
|
# Currently meson doesn't really atempt to handle pre-release versions, |
|
|
|
|
# so strip the 'svn' off the end, since it will probably cuase problems |
|
|
|
|
# for users who want the patch version. |
|
|
|
|
self.version = out.strip().rstrip('svn') |
|
|
|
|
|
|
|
|
|
p, out = Popen_safe( |
|
|
|
|
[self.llvmconfig, '--libs', '--ldflags', '--system-libs'])[:2] |
|
|
|
|
if p.returncode != 0: |
|
|
|
|
raise DependencyException('Could not generate libs for LLVM.') |
|
|
|
|
self.link_args = shlex.split(out) |
|
|
|
|
|
|
|
|
|
p, out = Popen_safe([self.llvmconfig, '--cppflags'])[:2] |
|
|
|
|
if p.returncode != 0: |
|
|
|
|
raise DependencyException('Could not generate includedir for LLVM.') |
|
|
|
|
cargs = mesonlib.OrderedSet(shlex.split(out)) |
|
|
|
|
self.compile_args = list(cargs.difference(self.__cpp_blacklist)) |
|
|
|
|
|
|
|
|
|
p, out = Popen_safe([self.llvmconfig, '--components'])[:2] |
|
|
|
|
if p.returncode != 0: |
|
|
|
|
raise DependencyException('Could not generate modules for LLVM.') |
|
|
|
|
self.modules = shlex.split(out) |
|
|
|
|
|
|
|
|
|
modules = mesonlib.stringlistify(mesonlib.flatten(kwargs.get('modules', []))) |
|
|
|
|
for mod in sorted(set(modules)): |
|
|
|
|
if mod not in self.modules: |
|
|
|
|
mlog.log('LLVM module', mod, 'found:', mlog.red('NO')) |
|
|
|
|
self.is_found = False |
|
|
|
@ -193,38 +196,33 @@ class LLVMDependency(ExternalDependency): |
|
|
|
|
else: |
|
|
|
|
mlog.log('LLVM module', mod, 'found:', mlog.green('YES')) |
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
def check_llvmconfig(cls, version_req): |
|
|
|
|
def check_llvmconfig(self, version_req): |
|
|
|
|
"""Try to find the highest version of llvm-config.""" |
|
|
|
|
for llvmconfig in cls.llvm_config_bins: |
|
|
|
|
for llvmconfig in self.llvm_config_bins: |
|
|
|
|
try: |
|
|
|
|
p, out = Popen_safe([llvmconfig, '--version'])[0:2] |
|
|
|
|
out = out.strip() |
|
|
|
|
if p.returncode != 0: |
|
|
|
|
continue |
|
|
|
|
# FIXME: As soon as some llvm-config is found, version checks |
|
|
|
|
# in further dependnecy() calls will be ignored |
|
|
|
|
if version_req: |
|
|
|
|
if version_compare(out, version_req, strict=True): |
|
|
|
|
if cls.__best_found and version_compare(out, '<={}'.format(cls.__best_found), strict=True): |
|
|
|
|
if self.__best_found and version_compare( |
|
|
|
|
out, '<={}'.format(self.__best_found), strict=True): |
|
|
|
|
continue |
|
|
|
|
cls.__best_found = out |
|
|
|
|
cls.llvmconfig = llvmconfig |
|
|
|
|
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. |
|
|
|
|
cls.__best_found = out |
|
|
|
|
cls.llvmconfig = llvmconfig |
|
|
|
|
self.__best_found = out |
|
|
|
|
self.llvmconfig = llvmconfig |
|
|
|
|
break |
|
|
|
|
except (FileNotFoundError, PermissionError): |
|
|
|
|
pass |
|
|
|
|
if cls.__best_found: |
|
|
|
|
if self.__best_found: |
|
|
|
|
mlog.log('Found llvm-config:', |
|
|
|
|
mlog.bold(shutil.which(cls.llvmconfig)), |
|
|
|
|
mlog.bold(shutil.which(self.llvmconfig)), |
|
|
|
|
'({})'.format(out.strip())) |
|
|
|
|
cls._llvmconfig_found = True |
|
|
|
|
else: |
|
|
|
|
cls.llvmconfig = False |
|
|
|
|
|
|
|
|
|
def need_threads(self): |
|
|
|
|
return True |
|
|
|
|