Simplified compiler finding logic and caching.
This commit is contained in:
parent
f7fe65102f
commit
8e066ebf2a
@ -34,6 +34,7 @@
|
||||
import spack.spec
|
||||
import spack.config
|
||||
from spack.compilation import get_path
|
||||
from spack.spec import CompilerSpec
|
||||
|
||||
description = "Manage compilers"
|
||||
|
||||
@ -50,8 +51,13 @@ def setup_parser(subparser):
|
||||
|
||||
list_parser = sp.add_parser('list', help='list available compilers')
|
||||
|
||||
info_parser = sp.add_parser('info', help='Show compiler paths.')
|
||||
info_parser.add_argument('compiler_spec')
|
||||
|
||||
|
||||
def compiler_add(args):
|
||||
"""Search either $PATH or a list of paths for compilers and add them
|
||||
to Spack's configuration."""
|
||||
paths = args.add_paths
|
||||
if not paths:
|
||||
paths = get_path('PATH')
|
||||
@ -64,9 +70,24 @@ def compiler_remove(args):
|
||||
pass
|
||||
|
||||
|
||||
def compiler_info(args):
|
||||
"""Print info about all compilers matching a spec."""
|
||||
cspec = CompilerSpec(args.compiler_spec)
|
||||
compilers = spack.compilers.compilers_for_spec(cspec)
|
||||
|
||||
if not compilers:
|
||||
tty.error("No compilers match spec %s." % cspec)
|
||||
else:
|
||||
for c in compilers:
|
||||
print str(c.spec) + ":"
|
||||
print "\tcc = %s" % c.cc
|
||||
print "\tcxx = %s" % c.cxx
|
||||
print "\tf77 = %s" % c.f77
|
||||
print "\tfc = %s" % c.fc
|
||||
|
||||
|
||||
def compiler_list(args):
|
||||
tty.msg("Available compilers")
|
||||
|
||||
index = index_by(spack.compilers.all_compilers(), 'name')
|
||||
for name, compilers in index.items():
|
||||
tty.hline(name, char='-', color=spack.spec.compiler_color)
|
||||
@ -76,6 +97,6 @@ def compiler_list(args):
|
||||
def compiler(parser, args):
|
||||
action = { 'add' : compiler_add,
|
||||
'remove' : compiler_remove,
|
||||
'info' : compiler_info,
|
||||
'list' : compiler_list }
|
||||
action[args.compiler_command](args)
|
||||
|
||||
|
@ -54,7 +54,7 @@ def get_compiler_version(compiler_path, version_arg, regex='(.*)'):
|
||||
output = compiler(version_arg, return_output=True, error=None)
|
||||
|
||||
match = re.search(regex, output)
|
||||
_version_cache[compiler_path] = match.group(1) if match else None
|
||||
_version_cache[compiler_path] = match.group(1) if match else 'unknown'
|
||||
|
||||
return _version_cache[compiler_path]
|
||||
|
||||
@ -95,7 +95,7 @@ class Compiler(object):
|
||||
arg_rpath = '-Wl,-rpath,%s'
|
||||
|
||||
|
||||
def __init__(self, cc, cxx, f77, fc, version=None):
|
||||
def __init__(self, cspec, cc, cxx, f77, fc):
|
||||
def check(exe):
|
||||
if exe is None:
|
||||
return None
|
||||
@ -107,55 +107,20 @@ def check(exe):
|
||||
self.f77 = check(f77)
|
||||
self.fc = check(fc)
|
||||
|
||||
# Allow versions to be memoized so we don't have to run
|
||||
# compilers many times. Record them in the version cache if
|
||||
# we get them in a constructor
|
||||
#
|
||||
# TODO: what to do if compilers have different versions?
|
||||
#
|
||||
self._version = version
|
||||
self._cache_version()
|
||||
self.spec = cspec
|
||||
|
||||
|
||||
@property
|
||||
def version(self):
|
||||
if not self._version:
|
||||
v = self.cc_version(self.cc)
|
||||
if v is not None:
|
||||
self._version = v
|
||||
return Version(v)
|
||||
|
||||
v = self.cxx_version(self.cxx)
|
||||
if v is not None:
|
||||
self._version = v
|
||||
return Version(v)
|
||||
|
||||
v = self.f77_version(self.f77)
|
||||
if v is not None:
|
||||
self._version = v
|
||||
return Version(v)
|
||||
|
||||
v = self.fc_version(self.fc)
|
||||
if v is not None:
|
||||
self._version = v
|
||||
return Version(v)
|
||||
|
||||
raise InvalidCompilerError()
|
||||
|
||||
return Version(self._version)
|
||||
|
||||
|
||||
def _cache_version(self):
|
||||
_version_cache[self.cc] = self._version
|
||||
_version_cache[self.cxx] = self._version
|
||||
_version_cache[self.f77] = self._version
|
||||
_version_cache[self.fc] = self._version
|
||||
|
||||
|
||||
@property
|
||||
def spec(self):
|
||||
return spack.spec.CompilerSpec(self.name, self.version)
|
||||
return self.spec.version
|
||||
|
||||
#
|
||||
# Compiler classes have methods for querying the version of
|
||||
# specific compiler executables. This is used when discovering compilers.
|
||||
#
|
||||
# Compiler *instances* are just data objects, and can only be
|
||||
# constructed from an actual set of executables.
|
||||
#
|
||||
|
||||
@classmethod
|
||||
def default_version(cls, cc):
|
||||
@ -237,16 +202,6 @@ def find(cls, *path):
|
||||
cxx_names, etc. and it will group them if they have common
|
||||
prefixes, suffixes, and versions. e.g., gcc-mp-4.7 would
|
||||
be grouped with g++-mp-4.7 and gfortran-mp-4.7.
|
||||
|
||||
Example return values::
|
||||
|
||||
[ gcc('/usr/bin/gcc', '/usr/bin/g++',
|
||||
'/usr/bin/gfortran', '/usr/bin/gfortran',
|
||||
Version('4.4.5')),
|
||||
gcc('/usr/bin/gcc-mp-4.5', '/usr/bin/g++-mp-4.5',
|
||||
'/usr/bin/gfortran-mp-4.5', '/usr/bin/gfortran-mp-4.5',
|
||||
Version('4.7.2')) ]
|
||||
|
||||
"""
|
||||
dicts = parmap(
|
||||
lambda t: cls._find_matches_in_path(*t),
|
||||
@ -263,8 +218,8 @@ def find(cls, *path):
|
||||
for k in all_keys:
|
||||
ver, pre, suf = k
|
||||
paths = tuple(pn[k] if k in pn else None for pn in dicts)
|
||||
args = paths + (ver,)
|
||||
compilers.append(cls(*args))
|
||||
spec = spack.spec.CompilerSpec(cls.name, ver)
|
||||
compilers.append(cls(spec, *paths))
|
||||
|
||||
return compilers
|
||||
|
||||
|
@ -118,7 +118,6 @@ def find_compilers(*path):
|
||||
# ensure all the version calls we made are cached in the parent
|
||||
# process, as well. This speeds up Spack a lot.
|
||||
clist = reduce(lambda x,y: x+y, compiler_lists)
|
||||
for c in clist: c._cache_version()
|
||||
return clist
|
||||
|
||||
|
||||
@ -191,8 +190,7 @@ def get_compiler(cspec):
|
||||
else:
|
||||
compiler_paths.append(None)
|
||||
|
||||
args = tuple(compiler_paths) + (compiler_spec.version,)
|
||||
return cls(*args)
|
||||
return cls(cspec, *compiler_paths)
|
||||
|
||||
matches = find(compiler_spec)
|
||||
return [get_compiler(cspec) for cspec in matches]
|
||||
|
@ -22,7 +22,7 @@
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
##############################################################################
|
||||
from spack.compiler import Compiler
|
||||
from spack.compiler import *
|
||||
|
||||
class Clang(Compiler):
|
||||
# Subclasses use possible names of C compiler
|
||||
@ -48,5 +48,4 @@ def default_version(self, comp):
|
||||
Thread model: posix
|
||||
"""
|
||||
return get_compiler_version(
|
||||
comp, '--version', r'clang version ([^ ]+)')
|
||||
|
||||
comp, '--version', r'(?:clang version|based on LLVM) ([^ )]+)')
|
||||
|
Loading…
Reference in New Issue
Block a user