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.
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
import os.path
|
||||||
from spack import *
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import llnl.util.tty as tty
|
||||||
|
import spack.util.executable
|
||||||
|
|
||||||
|
|
||||||
class Llvm(CMakePackage, CudaPackage):
|
class Llvm(CMakePackage, CudaPackage):
|
||||||
"""The LLVM Project is a collection of modular and reusable compiler and
|
"""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
|
# https://bugs.llvm.org/show_bug.cgi?id=39696
|
||||||
patch("thread-p9.patch", when="@develop+libcxx")
|
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')
|
@run_before('cmake')
|
||||||
def codesign_check(self):
|
def codesign_check(self):
|
||||||
if self.spec.satisfies("+code_signing"):
|
if self.spec.satisfies("+code_signing"):
|
||||||
|
Loading…
Reference in New Issue
Block a user