diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2016-06-20 09:34:25 -0700 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2016-06-20 09:34:25 -0700 |
commit | ce105e9bbe53e08cd4a4df4a8be0769b930abf8a (patch) | |
tree | 42e12a16303bfe8ddcdadf730092f97558397938 | |
parent | f9efb746d7f547d972fbe3d268b3aa67df478e55 (diff) | |
parent | 84e21703bde307c920e83e6cd4452feaacbaf5f2 (diff) | |
download | spack-ce105e9bbe53e08cd4a4df4a8be0769b930abf8a.tar.gz spack-ce105e9bbe53e08cd4a4df4a8be0769b930abf8a.tar.bz2 spack-ce105e9bbe53e08cd4a4df4a8be0769b930abf8a.tar.xz spack-ce105e9bbe53e08cd4a4df4a8be0769b930abf8a.zip |
Merge branch 'bugfix/compiler_find' into develop
-rw-r--r-- | lib/spack/spack/cmd/compiler.py | 15 | ||||
-rw-r--r-- | lib/spack/spack/compilers/__init__.py | 43 | ||||
-rw-r--r-- | lib/spack/spack/test/__init__.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/test_compiler_cmd.py | 81 |
4 files changed, 112 insertions, 29 deletions
diff --git a/lib/spack/spack/cmd/compiler.py b/lib/spack/spack/cmd/compiler.py index 030aa77c30..c95045ef85 100644 --- a/lib/spack/spack/cmd/compiler.py +++ b/lib/spack/spack/cmd/compiler.py @@ -69,7 +69,7 @@ def setup_parser(subparser): help="Configuration scope to read from.") -def compiler_add(args): +def compiler_find(args): """Search either $PATH or a list of paths OR MODULES for compilers and add them to Spack's configuration.""" paths = args.add_paths @@ -78,7 +78,6 @@ def compiler_add(args): compilers = [c for c in spack.compilers.find_compilers(*args.add_paths) if c.spec not in spack.compilers.all_compilers(scope=args.scope)] - if compilers: spack.compilers.add_compilers_to_config(compilers, scope=args.scope) n = len(compilers) @@ -93,7 +92,6 @@ def compiler_add(args): def compiler_remove(args): cspec = CompilerSpec(args.compiler_spec) compilers = spack.compilers.compilers_for_spec(cspec, scope=args.scope) - if not compilers: tty.die("No compilers match spec %s" % cspec) elif not args.all and len(compilers) > 1: @@ -137,9 +135,10 @@ def compiler_list(args): def compiler(parser, args): - action = { 'add' : compiler_add, - 'remove' : compiler_remove, - 'rm' : compiler_remove, - 'info' : compiler_info, - 'list' : compiler_list } + action = {'add' : compiler_find, + 'find' : compiler_find, + 'remove' : compiler_remove, + 'rm' : compiler_remove, + 'info' : compiler_info, + 'list' : compiler_list } action[args.compiler_command](args) diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py index 4b546c2cbf..ae72b743b2 100644 --- a/lib/spack/spack/compilers/__init__.py +++ b/lib/spack/spack/compilers/__init__.py @@ -52,6 +52,7 @@ from spack.util.environment import get_path _imported_compilers_module = 'spack.compilers' _path_instance_vars = ['cc', 'cxx', 'f77', 'fc'] _other_instance_vars = ['modules', 'operating_system'] +_cache_config_file = [] # TODO: customize order in config file if platform.system() == 'Darwin': @@ -79,9 +80,7 @@ def _to_dict(compiler): if compiler.alias: d['alias'] = compiler.alias - return { - 'compiler': d - } + return {'compiler': d} def get_compiler_config(scope=None): @@ -99,7 +98,6 @@ def get_compiler_config(scope=None): # Update the configuration if there are currently no compilers # configured. Avoid updating automatically if there ARE site # compilers configured but no user ones. -# if (isinstance(arch, basestring) or arch == my_arch) and arch not in config: if not config: if scope is None: # We know no compilers were configured in any scope. @@ -112,8 +110,11 @@ def get_compiler_config(scope=None): if not site_config: init_compiler_config() config = spack.config.get_config('compilers', scope=scope) - - return config + return config + elif config: + return config + else: + return [] # Return empty list which we will later append to. def add_compilers_to_config(compilers, scope=None): @@ -126,7 +127,8 @@ def add_compilers_to_config(compilers, scope=None): compiler_config = get_compiler_config(scope) for compiler in compilers: compiler_config.append(_to_dict(compiler)) - + global _cache_config_file + _cache_config_file = compiler_config spack.config.update_config('compilers', compiler_config, scope) @@ -139,15 +141,17 @@ def remove_compiler_from_config(compiler_spec, scope=None): - scope: configuration scope to modify. """ compiler_config = get_compiler_config(scope) - matches = [(a,c) for (a,c) in compiler_config.items() if c['spec'] == compiler_spec] - if len(matches) == 1: - del compiler_config[matches[0][0]] - else: + config_length = len(compiler_config) + + filtered_compiler_config = [comp for comp in compiler_config + if spack.spec.CompilerSpec(comp['compiler']['spec']) != compiler_spec] + # Need a better way for this + global _cache_config_file + _cache_config_file = filtered_compiler_config # Update the cache for changes + if len(filtered_compiler_config) == config_length: # No items removed CompilerSpecInsufficientlySpecificError(compiler_spec) + spack.config.update_config('compilers', filtered_compiler_config, scope) - spack.config.update_config('compilers', compiler_config, scope) - -_cache_config_file = {} def all_compilers_config(scope=None): """Return a set of specs for all the compiler versions currently @@ -155,14 +159,13 @@ def all_compilers_config(scope=None): """ # Get compilers for this architecture. global _cache_config_file #Create a cache of the config file so we don't load all the time. - if not _cache_config_file: _cache_config_file = get_compiler_config(scope) return _cache_config_file - else: return _cache_config_file + def all_compilers(scope=None): # Return compiler specs from the merged config. return [spack.spec.CompilerSpec(s['compiler']['spec']) @@ -181,7 +184,7 @@ def default_compiler(): return sorted(versions)[-1] -def find_compilers(): +def find_compilers(*paths): """Return a list of compilers found in the suppied paths. This invokes the find_compilers() method for each operating system associated with the host platform, and appends @@ -190,11 +193,11 @@ def find_compilers(): # Find compilers for each operating system class oss = all_os_classes() compiler_lists = [] - for os in oss: - compiler_lists.extend(os.find_compilers()) - + for o in oss: + compiler_lists.extend(o.find_compilers(*paths)) return compiler_lists + def supported_compilers(): """Return a set of names of compilers supported by Spack. diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py index 97f142e746..fb91f24721 100644 --- a/lib/spack/spack/test/__init__.py +++ b/lib/spack/spack/test/__init__.py @@ -40,7 +40,7 @@ test_names = ['architecture', 'versions', 'url_parse', 'url_substitution', 'pack 'cc', 'link_tree', 'spec_yaml', 'optional_deps', 'make_executable', 'configure_guess', 'lock', 'database', 'namespace_trie', 'yaml', 'sbang', 'environment', 'cmd.find', - 'cmd.uninstall', 'cmd.test_install'] + 'cmd.uninstall', 'cmd.test_install', 'cmd.test_compiler_cmd'] def list_tests(): diff --git a/lib/spack/spack/test/cmd/test_compiler_cmd.py b/lib/spack/spack/test/cmd/test_compiler_cmd.py new file mode 100644 index 0000000000..d89814154b --- /dev/null +++ b/lib/spack/spack/test/cmd/test_compiler_cmd.py @@ -0,0 +1,81 @@ +import os +import shutil +from tempfile import mkdtemp + +from llnl.util.filesystem import set_executable, mkdirp + +import spack.spec +import spack.cmd.compiler +import spack.compilers +from spack.version import Version +from spack.test.mock_packages_test import * + +test_version = '4.5-spacktest' + +class MockArgs(object): + def __init__(self, add_paths=[], scope=None, compiler_spec=None, all=None): + self.add_paths = add_paths + self.scope = scope + self.compiler_spec = compiler_spec + self.all = all + + +def make_mock_compiler(): + """Make a directory containing a fake, but detectable compiler.""" + mock_compiler_dir = mkdtemp() + bin_dir = os.path.join(mock_compiler_dir, 'bin') + mkdirp(bin_dir) + + gcc_path = os.path.join(bin_dir, 'gcc') + gxx_path = os.path.join(bin_dir, 'g++') + gfortran_path = os.path.join(bin_dir, 'gfortran') + + with open(gcc_path, 'w') as f: + f.write("""\ +#!/bin/sh + +for arg in "$@"; do + if [ "$arg" = -dumpversion ]; then + echo '%s' + fi +done +""" % test_version) + + # Create some mock compilers in the temporary directory + set_executable(gcc_path) + shutil.copy(gcc_path, gxx_path) + shutil.copy(gcc_path, gfortran_path) + + return mock_compiler_dir + + +class CompilerCmdTest(MockPackagesTest): + """ Test compiler commands for add and remove """ + + + def test_compiler_remove(self): + args = MockArgs(all=True, compiler_spec='gcc@4.5.0') + spack.cmd.compiler.compiler_remove(args) + compilers = spack.compilers.all_compilers() + self.assertTrue(spack.spec.CompilerSpec("gcc@4.5.0") not in compilers) + + + def test_compiler_add(self): + # compilers available by default. + old_compilers = set(spack.compilers.all_compilers()) + + # add our new compiler and find again. + compiler_dir = make_mock_compiler() + + try: + args = MockArgs(add_paths=[compiler_dir]) + spack.cmd.compiler.compiler_find(args) + + # ensure new compiler is in there + new_compilers = set(spack.compilers.all_compilers()) + new_compiler = new_compilers - old_compilers + self.assertTrue(new_compiler) + self.assertTrue(new_compiler.pop().version == Version(test_version)) + + finally: + shutil.rmtree(compiler_dir, ignore_errors=True) |