summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/cmd/compiler.py15
-rw-r--r--lib/spack/spack/compilers/__init__.py43
-rw-r--r--lib/spack/spack/test/__init__.py2
-rw-r--r--lib/spack/spack/test/cmd/test_compiler_cmd.py81
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)