From 8e066ebf2a0a94be9e4590c4828637adf951744e Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Mon, 23 Jun 2014 08:53:08 -0700 Subject: Simplified compiler finding logic and caching. --- lib/spack/spack/cmd/compiler.py | 25 +++++++++++- lib/spack/spack/compiler.py | 71 +++++++---------------------------- lib/spack/spack/compilers/__init__.py | 4 +- lib/spack/spack/compilers/clang.py | 5 +-- 4 files changed, 39 insertions(+), 66 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/cmd/compiler.py b/lib/spack/spack/cmd/compiler.py index af69897ce9..dc1d0546a7 100644 --- a/lib/spack/spack/cmd/compiler.py +++ b/lib/spack/spack/cmd/compiler.py @@ -34,6 +34,7 @@ import spack.compilers 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) - diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py index b04034bbdd..716356bdd2 100644 --- a/lib/spack/spack/compiler.py +++ b/lib/spack/spack/compiler.py @@ -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 @@ class Compiler(object): 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 @@ class Compiler(object): 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 @@ class Compiler(object): 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 diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py index 36d995b6bd..c5bfe21ed4 100644 --- a/lib/spack/spack/compilers/__init__.py +++ b/lib/spack/spack/compilers/__init__.py @@ -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 compilers_for_spec(compiler_spec): 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] diff --git a/lib/spack/spack/compilers/clang.py b/lib/spack/spack/compilers/clang.py index 73c462b49f..790901c86e 100644 --- a/lib/spack/spack/compilers/clang.py +++ b/lib/spack/spack/compilers/clang.py @@ -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 @@ class Clang(Compiler): Thread model: posix """ return get_compiler_version( - comp, '--version', r'clang version ([^ ]+)') - + comp, '--version', r'(?:clang version|based on LLVM) ([^ )]+)') -- cgit v1.2.3-70-g09d2