llvm: added external detection capabilities (#17989)
* llvm: added external detection capabilities * Added comment with reference to external package detection docs * Fix typo in a comment
This commit is contained in:
parent
5512340a51
commit
ecf4829de7
@ -2,10 +2,13 @@
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
from spack import *
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
import llnl.util.tty as tty
|
||||
import spack.util.executable
|
||||
|
||||
|
||||
class Llvm(CMakePackage, CudaPackage):
|
||||
"""The LLVM Project is a collection of modular and reusable compiler and
|
||||
@ -204,6 +207,108 @@ class Llvm(CMakePackage, CudaPackage):
|
||||
# https://bugs.llvm.org/show_bug.cgi?id=39696
|
||||
patch("thread-p9.patch", when="@develop+libcxx")
|
||||
|
||||
# The functions and attributes below implement external package
|
||||
# detection for LLVM. See:
|
||||
#
|
||||
# https://spack.readthedocs.io/en/latest/packaging_guide.html#making-a-package-discoverable-with-spack-external-find
|
||||
executables = ['clang', 'ld.lld', 'lldb']
|
||||
|
||||
@classmethod
|
||||
def filter_detected_exes(cls, prefix, exes_in_prefix):
|
||||
result = []
|
||||
for exe in exes_in_prefix:
|
||||
# Executables like lldb-vscode-X are daemon listening
|
||||
# on some port and would hang Spack during detection.
|
||||
# clang-cl and clang-cpp are dev tools that we don't
|
||||
# need to test
|
||||
if any(x in exe for x in ('vscode', 'cpp', '-cl', '-gpu')):
|
||||
continue
|
||||
result.append(exe)
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def determine_version(cls, exe):
|
||||
version_regex = re.compile(
|
||||
# Normal clang compiler versions are left as-is
|
||||
r'clang version ([^ )]+)-svn[~.\w\d-]*|'
|
||||
# Don't include hyphenated patch numbers in the version
|
||||
# (see https://github.com/spack/spack/pull/14365 for details)
|
||||
r'clang version ([^ )]+?)-[~.\w\d-]*|'
|
||||
r'clang version ([^ )]+)|'
|
||||
# LLDB
|
||||
r'lldb version ([^ )\n]+)|'
|
||||
# LLD
|
||||
r'LLD ([^ )\n]+) \(compatible with GNU linkers\)'
|
||||
)
|
||||
try:
|
||||
compiler = Executable(exe)
|
||||
output = compiler('--version', output=str, error=str)
|
||||
if 'Apple' in output:
|
||||
return None
|
||||
match = version_regex.search(output)
|
||||
if match:
|
||||
return match.group(match.lastindex)
|
||||
except spack.util.executable.ProcessError:
|
||||
pass
|
||||
except Exception as e:
|
||||
tty.debug(e)
|
||||
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def determine_variants(cls, exes, version_str):
|
||||
variants, compilers = ['+clang'], {}
|
||||
lld_found, lldb_found = False, False
|
||||
for exe in exes:
|
||||
if 'clang++' in exe:
|
||||
compilers['cxx'] = exe
|
||||
elif 'clang' in exe:
|
||||
compilers['c'] = exe
|
||||
elif 'ld.lld' in exe:
|
||||
lld_found = True
|
||||
compilers['ld'] = exe
|
||||
elif 'lldb' in exe:
|
||||
lldb_found = True
|
||||
compilers['lldb'] = exe
|
||||
|
||||
variants.append('+lld' if lld_found else '~lld')
|
||||
variants.append('+lldb' if lldb_found else '~lldb')
|
||||
|
||||
return ''.join(variants), {'compilers': compilers}
|
||||
|
||||
@classmethod
|
||||
def validate_detected_spec(cls, spec, extra_attributes):
|
||||
# For LLVM 'compilers' is a mandatory attribute
|
||||
msg = ('the extra attribute "compilers" must be set for '
|
||||
'the detected spec "{0}"'.format(spec))
|
||||
assert 'compilers' in extra_attributes, msg
|
||||
compilers = extra_attributes['compilers']
|
||||
for key in ('c', 'cxx'):
|
||||
msg = '{0} compiler not found for {1}'
|
||||
assert key in compilers, msg.format(key, spec)
|
||||
|
||||
@property
|
||||
def cc(self):
|
||||
msg = "cannot retrieve C compiler [spec is not concrete]"
|
||||
assert self.spec.concrete, msg
|
||||
if self.spec.external:
|
||||
return self.spec.extra_attributes['compilers'].get('c', None)
|
||||
result = None
|
||||
if '+clang' in self.spec:
|
||||
result = os.path.join(self.spec.prefix.bin, 'clang')
|
||||
return result
|
||||
|
||||
@property
|
||||
def cxx(self):
|
||||
msg = "cannot retrieve C++ compiler [spec is not concrete]"
|
||||
assert self.spec.concrete, msg
|
||||
if self.spec.external:
|
||||
return self.spec.extra_attributes['compilers'].get('cxx', None)
|
||||
result = None
|
||||
if '+clang' in self.spec:
|
||||
result = os.path.join(self.spec.prefix.bin, 'clang++')
|
||||
return result
|
||||
|
||||
@run_before('cmake')
|
||||
def codesign_check(self):
|
||||
if self.spec.satisfies("+code_signing"):
|
||||
|
Loading…
Reference in New Issue
Block a user