Simplified compiler finding logic and caching.
This commit is contained in:
parent
f7fe65102f
commit
8e066ebf2a
@ -34,6 +34,7 @@
|
|||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.config
|
import spack.config
|
||||||
from spack.compilation import get_path
|
from spack.compilation import get_path
|
||||||
|
from spack.spec import CompilerSpec
|
||||||
|
|
||||||
description = "Manage compilers"
|
description = "Manage compilers"
|
||||||
|
|
||||||
@ -50,8 +51,13 @@ def setup_parser(subparser):
|
|||||||
|
|
||||||
list_parser = sp.add_parser('list', help='list available compilers')
|
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):
|
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
|
paths = args.add_paths
|
||||||
if not paths:
|
if not paths:
|
||||||
paths = get_path('PATH')
|
paths = get_path('PATH')
|
||||||
@ -64,9 +70,24 @@ def compiler_remove(args):
|
|||||||
pass
|
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):
|
def compiler_list(args):
|
||||||
tty.msg("Available compilers")
|
tty.msg("Available compilers")
|
||||||
|
|
||||||
index = index_by(spack.compilers.all_compilers(), 'name')
|
index = index_by(spack.compilers.all_compilers(), 'name')
|
||||||
for name, compilers in index.items():
|
for name, compilers in index.items():
|
||||||
tty.hline(name, char='-', color=spack.spec.compiler_color)
|
tty.hline(name, char='-', color=spack.spec.compiler_color)
|
||||||
@ -76,6 +97,6 @@ def compiler_list(args):
|
|||||||
def compiler(parser, args):
|
def compiler(parser, args):
|
||||||
action = { 'add' : compiler_add,
|
action = { 'add' : compiler_add,
|
||||||
'remove' : compiler_remove,
|
'remove' : compiler_remove,
|
||||||
|
'info' : compiler_info,
|
||||||
'list' : compiler_list }
|
'list' : compiler_list }
|
||||||
action[args.compiler_command](args)
|
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)
|
output = compiler(version_arg, return_output=True, error=None)
|
||||||
|
|
||||||
match = re.search(regex, output)
|
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]
|
return _version_cache[compiler_path]
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ class Compiler(object):
|
|||||||
arg_rpath = '-Wl,-rpath,%s'
|
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):
|
def check(exe):
|
||||||
if exe is None:
|
if exe is None:
|
||||||
return None
|
return None
|
||||||
@ -107,55 +107,20 @@ def check(exe):
|
|||||||
self.f77 = check(f77)
|
self.f77 = check(f77)
|
||||||
self.fc = check(fc)
|
self.fc = check(fc)
|
||||||
|
|
||||||
# Allow versions to be memoized so we don't have to run
|
self.spec = cspec
|
||||||
# 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()
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def version(self):
|
def version(self):
|
||||||
if not self._version:
|
return self.spec.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)
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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
|
@classmethod
|
||||||
def default_version(cls, cc):
|
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
|
cxx_names, etc. and it will group them if they have common
|
||||||
prefixes, suffixes, and versions. e.g., gcc-mp-4.7 would
|
prefixes, suffixes, and versions. e.g., gcc-mp-4.7 would
|
||||||
be grouped with g++-mp-4.7 and gfortran-mp-4.7.
|
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(
|
dicts = parmap(
|
||||||
lambda t: cls._find_matches_in_path(*t),
|
lambda t: cls._find_matches_in_path(*t),
|
||||||
@ -263,8 +218,8 @@ def find(cls, *path):
|
|||||||
for k in all_keys:
|
for k in all_keys:
|
||||||
ver, pre, suf = k
|
ver, pre, suf = k
|
||||||
paths = tuple(pn[k] if k in pn else None for pn in dicts)
|
paths = tuple(pn[k] if k in pn else None for pn in dicts)
|
||||||
args = paths + (ver,)
|
spec = spack.spec.CompilerSpec(cls.name, ver)
|
||||||
compilers.append(cls(*args))
|
compilers.append(cls(spec, *paths))
|
||||||
|
|
||||||
return compilers
|
return compilers
|
||||||
|
|
||||||
|
@ -118,7 +118,6 @@ def find_compilers(*path):
|
|||||||
# ensure all the version calls we made are cached in the parent
|
# ensure all the version calls we made are cached in the parent
|
||||||
# process, as well. This speeds up Spack a lot.
|
# process, as well. This speeds up Spack a lot.
|
||||||
clist = reduce(lambda x,y: x+y, compiler_lists)
|
clist = reduce(lambda x,y: x+y, compiler_lists)
|
||||||
for c in clist: c._cache_version()
|
|
||||||
return clist
|
return clist
|
||||||
|
|
||||||
|
|
||||||
@ -191,8 +190,7 @@ def get_compiler(cspec):
|
|||||||
else:
|
else:
|
||||||
compiler_paths.append(None)
|
compiler_paths.append(None)
|
||||||
|
|
||||||
args = tuple(compiler_paths) + (compiler_spec.version,)
|
return cls(cspec, *compiler_paths)
|
||||||
return cls(*args)
|
|
||||||
|
|
||||||
matches = find(compiler_spec)
|
matches = find(compiler_spec)
|
||||||
return [get_compiler(cspec) for cspec in matches]
|
return [get_compiler(cspec) for cspec in matches]
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from spack.compiler import Compiler
|
from spack.compiler import *
|
||||||
|
|
||||||
class Clang(Compiler):
|
class Clang(Compiler):
|
||||||
# Subclasses use possible names of C compiler
|
# Subclasses use possible names of C compiler
|
||||||
@ -48,5 +48,4 @@ def default_version(self, comp):
|
|||||||
Thread model: posix
|
Thread model: posix
|
||||||
"""
|
"""
|
||||||
return get_compiler_version(
|
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