summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2020-08-13 16:03:09 +0200
committerGitHub <noreply@github.com>2020-08-13 09:03:09 -0500
commitecf4829de7b9683a680176e9dff85ba11c0f03d9 (patch)
tree90bff4a309666c9c3a97273b1ac446dcf72df2ed
parent5512340a51f015a3655492f749db0f671621cd42 (diff)
downloadspack-ecf4829de7b9683a680176e9dff85ba11c0f03d9.tar.gz
spack-ecf4829de7b9683a680176e9dff85ba11c0f03d9.tar.bz2
spack-ecf4829de7b9683a680176e9dff85ba11c0f03d9.tar.xz
spack-ecf4829de7b9683a680176e9dff85ba11c0f03d9.zip
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
-rw-r--r--var/spack/repos/builtin/packages/llvm/package.py109
1 files changed, 107 insertions, 2 deletions
diff --git a/var/spack/repos/builtin/packages/llvm/package.py b/var/spack/repos/builtin/packages/llvm/package.py
index 9573c5d715..95ffcc51fd 100644
--- a/var/spack/repos/builtin/packages/llvm/package.py
+++ b/var/spack/repos/builtin/packages/llvm/package.py
@@ -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"):