diff options
61 files changed, 1484 insertions, 378 deletions
diff --git a/.gitignore b/.gitignore index b1215f0c7e..072bf30c07 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ /etc/spackconfig /share/spack/dotkit /share/spack/modules +/share/spack/lmod /TAGS /htmlcov .coverage diff --git a/lib/spack/spack/abi.py b/lib/spack/spack/abi.py index 064abb9782..7a6f9c3f40 100644 --- a/lib/spack/spack/abi.py +++ b/lib/spack/spack/abi.py @@ -54,10 +54,10 @@ class ABI(object): output = None if compiler.cxx: rungcc = Executable(compiler.cxx) - libname = "libstdc++.so" + libname = "libstdc++." + dso_suffix elif compiler.cc: rungcc = Executable(compiler.cc) - libname = "libgcc_s.so" + libname = "libgcc_s." + dso_suffix else: return None try: diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py index f69f434afd..6b1561b7fc 100644 --- a/lib/spack/spack/cmd/__init__.py +++ b/lib/spack/spack/cmd/__init__.py @@ -69,17 +69,17 @@ def get_cmd_function_name(name): def get_module(name): """Imports the module for a particular command name and returns it.""" module_name = "%s.%s" % (__name__, name) - module = __import__( - module_name, fromlist=[name, SETUP_PARSER, DESCRIPTION], - level=0) + module = __import__(module_name, + fromlist=[name, SETUP_PARSER, DESCRIPTION], + level=0) attr_setdefault(module, SETUP_PARSER, lambda *args: None) # null-op attr_setdefault(module, DESCRIPTION, "") fn_name = get_cmd_function_name(name) if not hasattr(module, fn_name): - tty.die("Command module %s (%s) must define function '%s'." - % (module.__name__, module.__file__, fn_name)) + tty.die("Command module %s (%s) must define function '%s'." % + (module.__name__, module.__file__, fn_name)) return module diff --git a/lib/spack/spack/cmd/location.py b/lib/spack/spack/cmd/location.py index b9c8b5c330..54f7185707 100644 --- a/lib/spack/spack/cmd/location.py +++ b/lib/spack/spack/cmd/location.py @@ -25,7 +25,6 @@ import argparse import llnl.util.tty as tty -from llnl.util.filesystem import join_path import spack import spack.cmd @@ -77,7 +76,7 @@ def location(parser, args): print spack.prefix elif args.packages: - print spack.repo.root + print spack.repo.first_repo().root elif args.stages: print spack.stage_path @@ -99,7 +98,7 @@ def location(parser, args): if args.package_dir: # This one just needs the spec name. - print join_path(spack.repo.root, spec.name) + print spack.repo.dirname_for_package_name(spec.name) else: # These versions need concretized specs. diff --git a/lib/spack/spack/cmd/module.py b/lib/spack/spack/cmd/module.py index 2d0b83fe00..c6fa84109e 100644 --- a/lib/spack/spack/cmd/module.py +++ b/lib/spack/spack/cmd/module.py @@ -29,10 +29,10 @@ import os import shutil import sys +import llnl.util.filesystem as filesystem import llnl.util.tty as tty import spack.cmd import spack.cmd.common.arguments as arguments -import llnl.util.filesystem as filesystem from spack.modules import module_types description = "Manipulate module files" diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py index 73286483ef..8ef7d3c480 100644 --- a/lib/spack/spack/directory_layout.py +++ b/lib/spack/spack/directory_layout.py @@ -423,7 +423,7 @@ class RemoveFailedError(DirectoryLayoutError): def __init__(self, installed_spec, prefix, error): super(RemoveFailedError, self).__init__( 'Could not remove prefix %s for %s : %s' - % prefix, installed_spec.short_spec, error) + % (prefix, installed_spec.short_spec, error)) self.cause = error diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index 4349e32d4f..21802c4556 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -306,7 +306,7 @@ class URLFetchStrategy(FetchStrategy): if not self.archive_file: raise NoArchiveFileError("Cannot call archive() before fetching.") - shutil.copy(self.archive_file, destination) + shutil.copyfile(self.archive_file, destination) @_needs_stage def check(self): diff --git a/lib/spack/spack/hooks/__init__.py b/lib/spack/spack/hooks/__init__.py index c7c84defa0..ff4ebc2e57 100644 --- a/lib/spack/spack/hooks/__init__.py +++ b/lib/spack/spack/hooks/__init__.py @@ -24,7 +24,7 @@ ############################################################################## """This package contains modules with hooks for various stages in the Spack install process. You can add modules here and they'll be - executaed by package at various times during the package lifecycle. + executed by package at various times during the package lifecycle. Each hook is just a function that takes a package as a parameter. Hooks are not executed in any particular order. @@ -41,9 +41,10 @@ features. """ import imp -from llnl.util.lang import memoized, list_modules -from llnl.util.filesystem import join_path + import spack +from llnl.util.filesystem import join_path +from llnl.util.lang import memoized, list_modules @memoized @@ -70,12 +71,11 @@ class HookRunner(object): if hasattr(hook, '__call__'): hook(pkg) - # # Define some functions that can be called to fire off hooks. # -pre_install = HookRunner('pre_install') -post_install = HookRunner('post_install') +pre_install = HookRunner('pre_install') +post_install = HookRunner('post_install') -pre_uninstall = HookRunner('pre_uninstall') +pre_uninstall = HookRunner('pre_uninstall') post_uninstall = HookRunner('post_uninstall') diff --git a/lib/spack/spack/hooks/lmodmodule.py b/lib/spack/spack/hooks/lmodmodule.py new file mode 100644 index 0000000000..6b4318b1d0 --- /dev/null +++ b/lib/spack/spack/hooks/lmodmodule.py @@ -0,0 +1,35 @@ +############################################################################## +# Copyright (c) 2013, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://scalability-llnl.github.io/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License (as published by +# the Free Software Foundation) version 2.1 dated February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## +import spack.modules + + +def post_install(pkg): + dk = spack.modules.LmodModule(pkg.spec) + dk.write() + + +def post_uninstall(pkg): + dk = spack.modules.LmodModule(pkg.spec) + dk.remove() diff --git a/lib/spack/spack/modules.py b/lib/spack/spack/modules.py index 3db08a6e90..aa3ad5843f 100644 --- a/lib/spack/spack/modules.py +++ b/lib/spack/spack/modules.py @@ -40,6 +40,7 @@ module file. """ import copy import datetime +import itertools import os import os.path import re @@ -48,6 +49,7 @@ import textwrap import llnl.util.tty as tty import spack +import spack.compilers # Needed by LmodModules import spack.config from llnl.util.filesystem import join_path, mkdirp from spack.build_environment import parent_class_modules @@ -56,7 +58,8 @@ from spack.environment import * __all__ = ['EnvModule', 'Dotkit', 'TclModule'] -# Registry of all types of modules. Entries created by EnvModule's metaclass +"""Registry of all types of modules. Entries created by EnvModule's + metaclass.""" module_types = {} CONFIGURATION = spack.config.get_config('modules') @@ -389,6 +392,7 @@ class EnvModule(object): for mod in modules: set_module_variables_for_package(package, mod) set_module_variables_for_package(package, package.module) + package.setup_environment(spack_env, env) package.setup_dependent_package(self.pkg.module, self.spec) package.setup_dependent_environment(spack_env, env, self.spec) @@ -633,3 +637,237 @@ class TclModule(EnvModule): raise SystemExit('Module generation aborted.') line = line.format(**naming_tokens) yield line + +# To construct an arbitrary hierarchy of module files: +# 1. Parse the configuration file and check that all the items in +# hierarchical_scheme are indeed virtual packages +# This needs to be done only once at start-up +# 2. Order the stack as `hierarchical_scheme + ['mpi, 'compiler'] +# 3. Check which of the services are provided by the package +# -> may be more than one +# 4. Check which of the services are needed by the package +# -> this determines where to write the module file +# 5. For each combination of services in which we have at least one provider +# here add the appropriate conditional MODULEPATH modifications + + +class LmodModule(EnvModule): + name = 'lmod' + path = join_path(spack.share_path, "lmod") + + environment_modifications_formats = { + PrependPath: 'prepend_path("{name}", "{value}")\n', + AppendPath: 'append_path("{name}", "{value}")\n', + RemovePath: 'remove_path("{name}", "{value}")\n', + SetEnv: 'setenv("{name}", "{value}")\n', + UnsetEnv: 'unsetenv("{name}")\n' + } + + autoload_format = ('if not isloaded("{module_file}") then\n' + ' LmodMessage("Autoloading {module_file}")\n' + ' load("{module_file}")\n' + 'end\n\n') + + prerequisite_format = 'prereq("{module_file}")\n' + + family_format = 'family("{family}")\n' + + path_part_with_hash = join_path('{token.name}', '{token.version}-{token.hash}') # NOQA: ignore=E501 + path_part_without_hash = join_path('{token.name}', '{token.version}') + + # TODO : Check that extra tokens specified in configuration file + # TODO : are actually virtual dependencies + configuration = CONFIGURATION.get('lmod', {}) + hierarchy_tokens = configuration.get('hierarchical_scheme', []) + hierarchy_tokens = hierarchy_tokens + ['mpi', 'compiler'] + + def __init__(self, spec=None): + super(LmodModule, self).__init__(spec) + # Sets the root directory for this architecture + self.modules_root = join_path(LmodModule.path, self.spec.architecture) + # Retrieve core compilers + self.core_compilers = self.configuration.get('core_compilers', []) + # Keep track of the requirements that this package has in terms + # of virtual packages + # that participate in the hierarchical structure + self.requires = {'compiler': self.spec.compiler} + # For each virtual dependency in the hierarchy + for x in self.hierarchy_tokens: + if x in self.spec and not self.spec.package.provides( + x): # if I depend on it + self.requires[x] = self.spec[x] # record the actual provider + # Check what are the services I need (this will determine where the + # module file will be written) + self.substitutions = {} + self.substitutions.update(self.requires) + # TODO : complete substitutions + # Check what service I provide to others + self.provides = {} + # If it is in the list of supported compilers family -> compiler + if self.spec.name in spack.compilers.supported_compilers(): + self.provides['compiler'] = spack.spec.CompilerSpec(str(self.spec)) + # Special case for llvm + if self.spec.name == 'llvm': + self.provides['compiler'] = spack.spec.CompilerSpec(str(self.spec)) + self.provides['compiler'].name = 'clang' + + for x in self.hierarchy_tokens: + if self.spec.package.provides(x): + self.provides[x] = self.spec[x] + + def _hierarchy_token_combinations(self): + """ + Yields all the relevant combinations that could appear in the hierarchy + """ + for ii in range(len(self.hierarchy_tokens) + 1): + for item in itertools.combinations(self.hierarchy_tokens, ii): + if 'compiler' in item: + yield item + + def _hierarchy_to_be_provided(self): + """ + Filters a list of hierarchy tokens and yields only the one that we + need to provide + """ + for item in self._hierarchy_token_combinations(): + if any(x in self.provides for x in item): + yield item + + def token_to_path(self, name, value): + # If we are dealing with a core compiler, return 'Core' + if name == 'compiler' and str(value) in self.core_compilers: + return 'Core' + # CompilerSpec does not have an hash + if name == 'compiler': + return self.path_part_without_hash.format(token=value) + # For virtual providers add a small part of the hash + # to distinguish among different variants in a directory hierarchy + value.hash = value.dag_hash(length=6) + return self.path_part_with_hash.format(token=value) + + @property + def file_name(self): + parts = [self.token_to_path(x, self.requires[x]) + for x in self.hierarchy_tokens if x in self.requires] + hierarchy_name = join_path(*parts) + fullname = join_path(self.modules_root, hierarchy_name, + self.use_name + '.lua') + return fullname + + @property + def use_name(self): + return self.token_to_path('', self.spec) + + def modulepath_modifications(self): + # What is available is what we require plus what we provide + entry = '' + available = {} + available.update(self.requires) + available.update(self.provides) + available_parts = [self.token_to_path(x, available[x]) + for x in self.hierarchy_tokens if x in available] + # Missing parts + missing = [x for x in self.hierarchy_tokens if x not in available] + # Direct path we provide on top of compilers + modulepath = join_path(self.modules_root, *available_parts) + env = EnvironmentModifications() + env.prepend_path('MODULEPATH', modulepath) + for line in self.process_environment_command(env): + entry += line + + def local_variable(x): + lower, upper = x.lower(), x.upper() + fmt = 'local {lower}_name = os.getenv("LMOD_{upper}_NAME")\n' + fmt += 'local {lower}_version = os.getenv("LMOD_{upper}_VERSION")\n' # NOQA: ignore=501 + return fmt.format(lower=lower, upper=upper) + + def set_variables_for_service(env, x): + upper = x.upper() + s = self.provides[x] + name, version = os.path.split(self.token_to_path(x, s)) + + env.set('LMOD_{upper}_NAME'.format(upper=upper), name) + env.set('LMOD_{upper}_VERSION'.format(upper=upper), version) + + def conditional_modulepath_modifications(item): + entry = 'if ' + needed = [] + for x in self.hierarchy_tokens: + if x in missing: + needed.append('{x}_name '.format(x=x)) + entry += 'and '.join(needed) + 'then\n' + entry += ' local t = pathJoin("{root}"'.format( + root=self.modules_root) + for x in item: + if x in missing: + entry += ', {lower}_name, {lower}_version'.format( + lower=x.lower()) + else: + entry += ', "{x}"'.format( + x=self.token_to_path(x, available[x])) + entry += ')\n' + entry += ' prepend_path("MODULEPATH", t)\n' + entry += 'end\n\n' + return entry + + if 'compiler' not in self.provides: + # Retrieve variables + entry += '\n' + for x in missing: + entry += local_variable(x) + entry += '\n' + # Conditional modifications + conditionals = [x + for x in self._hierarchy_to_be_provided() + if any(t in missing for t in x)] + for item in conditionals: + entry += conditional_modulepath_modifications(item) + + # Set environment variables for the services we provide + env = EnvironmentModifications() + for x in self.provides: + set_variables_for_service(env, x) + for line in self.process_environment_command(env): + entry += line + + return entry + + @property + def header(self): + timestamp = datetime.datetime.now() + # Header as in + # https://www.tacc.utexas.edu/research-development/tacc-projects/lmod/advanced-user-guide/more-about-writing-module-files + header = "-- -*- lua -*-\n" + header += '-- Module file created by spack (https://github.com/LLNL/spack) on %s\n' % timestamp # NOQA: ignore=E501 + header += '--\n' + header += '-- %s\n' % self.spec.short_spec + header += '--\n' + + # Short description -> whatis() + if self.short_description: + header += "whatis([[Name : {name}]])\n".format(name=self.spec.name) + header += "whatis([[Version : {version}]])\n".format( + version=self.spec.version) + + # Long description -> help() + if self.long_description: + doc = re.sub(r'"', '\"', self.long_description) + header += "help([[{documentation}]])\n".format(documentation=doc) + + # Certain things need to be done only if we provide a service + if self.provides: + # Add family directives + header += '\n' + for x in self.provides: + header += self.family_format.format(family=x) + header += '\n' + header += '-- MODULEPATH modifications\n' + header += '\n' + # Modify MODULEPATH + header += self.modulepath_modifications() + # Set environment variables for services we provide + header += '\n' + header += '-- END MODULEPATH modifications\n' + header += '\n' + + return header diff --git a/lib/spack/spack/operating_systems/mac_os.py b/lib/spack/spack/operating_systems/mac_os.py index 3e5ab9b2e9..dafb5c1d41 100644 --- a/lib/spack/spack/operating_systems/mac_os.py +++ b/lib/spack/spack/operating_systems/mac_os.py @@ -22,7 +22,7 @@ class MacOs(OperatingSystem): "10.11": "elcapitan", "10.12": "sierra"} - mac_ver = py_platform.mac_ver()[0][:-2] + mac_ver = '.'.join(py_platform.mac_ver()[0].split('.')[:2]) name = mac_releases.get(mac_ver, "macos") super(MacOs, self).__init__(name, mac_ver) diff --git a/lib/spack/spack/schema/modules.py b/lib/spack/spack/schema/modules.py index f8066919f1..bdc70c9ef1 100644 --- a/lib/spack/spack/schema/modules.py +++ b/lib/spack/spack/schema/modules.py @@ -139,7 +139,20 @@ schema = { 'default': [], 'items': { 'type': 'string', - 'enum': ['tcl', 'dotkit']}}, + 'enum': ['tcl', 'dotkit', 'lmod']}}, + 'lmod': { + 'allOf': [ + # Base configuration + {'$ref': '#/definitions/module_type_configuration'}, + { + 'core_compilers': { + '$ref': '#/definitions/array_of_strings' + }, + 'hierarchical_scheme': { + '$ref': '#/definitions/array_of_strings' + } + } # Specific lmod extensions + ]}, 'tcl': { 'allOf': [ # Base configuration diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py index 22b1f17890..b114bbacb8 100644 --- a/lib/spack/spack/test/database.py +++ b/lib/spack/spack/test/database.py @@ -26,8 +26,8 @@ These tests check the database is functioning properly, both in memory and in its file """ -import os.path import multiprocessing +import os.path import spack from llnl.util.filesystem import join_path @@ -88,16 +88,16 @@ class DatabaseTest(MockDatabase): # query specs with multiple configurations mpileaks_specs = [s for s in all_specs if s.satisfies('mpileaks')] callpath_specs = [s for s in all_specs if s.satisfies('callpath')] - mpi_specs = [s for s in all_specs if s.satisfies('mpi')] + mpi_specs = [s for s in all_specs if s.satisfies('mpi')] self.assertEqual(len(mpileaks_specs), 3) self.assertEqual(len(callpath_specs), 3) self.assertEqual(len(mpi_specs), 3) # query specs with single configurations - dyninst_specs = [s for s in all_specs if s.satisfies('dyninst')] + dyninst_specs = [s for s in all_specs if s.satisfies('dyninst')] libdwarf_specs = [s for s in all_specs if s.satisfies('libdwarf')] - libelf_specs = [s for s in all_specs if s.satisfies('libelf')] + libelf_specs = [s for s in all_specs if s.satisfies('libelf')] self.assertEqual(len(dyninst_specs), 1) self.assertEqual(len(libdwarf_specs), 1) @@ -163,16 +163,16 @@ class DatabaseTest(MockDatabase): # query specs with multiple configurations mpileaks_specs = self.installed_db.query('mpileaks') callpath_specs = self.installed_db.query('callpath') - mpi_specs = self.installed_db.query('mpi') + mpi_specs = self.installed_db.query('mpi') self.assertEqual(len(mpileaks_specs), 3) self.assertEqual(len(callpath_specs), 3) self.assertEqual(len(mpi_specs), 3) # query specs with single configurations - dyninst_specs = self.installed_db.query('dyninst') + dyninst_specs = self.installed_db.query('dyninst') libdwarf_specs = self.installed_db.query('libdwarf') - libelf_specs = self.installed_db.query('libelf') + libelf_specs = self.installed_db.query('libelf') self.assertEqual(len(dyninst_specs), 1) self.assertEqual(len(libdwarf_specs), 1) diff --git a/lib/spack/spack/test/modules.py b/lib/spack/spack/test/modules.py index 55b771fc79..c4cf2865bb 100644 --- a/lib/spack/spack/test/modules.py +++ b/lib/spack/spack/test/modules.py @@ -49,105 +49,10 @@ def mock_open(filename, mode): handle.close() -configuration_autoload_direct = { - 'enable': ['tcl'], - 'tcl': { - 'all': { - 'autoload': 'direct' - } - } -} - -configuration_autoload_all = { - 'enable': ['tcl'], - 'tcl': { - 'all': { - 'autoload': 'all' - } - } -} - -configuration_prerequisites_direct = { - 'enable': ['tcl'], - 'tcl': { - 'all': { - 'prerequisites': 'direct' - } - } -} - -configuration_prerequisites_all = { - 'enable': ['tcl'], - 'tcl': { - 'all': { - 'prerequisites': 'all' - } - } -} - -configuration_alter_environment = { - 'enable': ['tcl'], - 'tcl': { - 'all': { - 'filter': {'environment_blacklist': ['CMAKE_PREFIX_PATH']}, - 'environment': { - 'set': {'{name}_ROOT': '{prefix}'} - } - }, - 'platform=test target=x86_64': { - 'environment': { - 'set': {'FOO': 'foo'}, - 'unset': ['BAR'] - } - }, - 'platform=test target=x86_32': { - 'load': ['foo/bar'] - } - } -} - -configuration_blacklist = { - 'enable': ['tcl'], - 'tcl': { - 'whitelist': ['zmpi'], - 'blacklist': ['callpath', 'mpi'], - 'all': { - 'autoload': 'direct' - } - } -} - -configuration_conflicts = { - 'enable': ['tcl'], - 'tcl': { - 'naming_scheme': '{name}/{version}-{compiler.name}', - 'all': { - 'conflict': ['{name}', 'intel/14.0.1'] - } - } -} - -configuration_wrong_conflicts = { - 'enable': ['tcl'], - 'tcl': { - 'naming_scheme': '{name}/{version}-{compiler.name}', - 'all': { - 'conflict': ['{name}/{compiler.name}'] - } - } -} - -configuration_suffix = { - 'enable': ['tcl'], - 'tcl': { - 'mpileaks': { - 'suffixes': { - '+debug': 'foo', - '~debug': 'bar' - } - } - } -} +# Spec strings that will be used throughout the tests +mpich_spec_string = 'mpich@3.0.4' +mpileaks_spec_string = 'mpileaks' +libdwarf_spec_string = 'libdwarf arch=x64-linux' class HelperFunctionsTests(MockPackagesTest): @@ -187,44 +92,156 @@ class HelperFunctionsTests(MockPackagesTest): self.assertTrue('CPATH' in names) -class TclTests(MockPackagesTest): +class ModuleFileGeneratorTests(MockPackagesTest): + """ + Base class to test module file generators. Relies on child having defined + a 'factory' attribute to create an instance of the generator to be tested. + """ def setUp(self): - super(TclTests, self).setUp() - self.configuration_obj = spack.modules.CONFIGURATION + super(ModuleFileGeneratorTests, self).setUp() + self.configuration_instance = spack.modules.CONFIGURATION + self.module_types_instance = spack.modules.module_types spack.modules.open = mock_open # Make sure that a non-mocked configuration will trigger an error spack.modules.CONFIGURATION = None + spack.modules.module_types = {self.factory.name: self.factory} def tearDown(self): del spack.modules.open - spack.modules.CONFIGURATION = self.configuration_obj - super(TclTests, self).tearDown() + spack.modules.module_types = self.module_types_instance + spack.modules.CONFIGURATION = self.configuration_instance + super(ModuleFileGeneratorTests, self).tearDown() def get_modulefile_content(self, spec): spec.concretize() - generator = spack.modules.TclModule(spec) + generator = self.factory(spec) generator.write() content = FILE_REGISTRY[generator.file_name].split('\n') return content + +class TclTests(ModuleFileGeneratorTests): + + factory = spack.modules.TclModule + + configuration_autoload_direct = { + 'enable': ['tcl'], + 'tcl': { + 'all': { + 'autoload': 'direct' + } + } + } + + configuration_autoload_all = { + 'enable': ['tcl'], + 'tcl': { + 'all': { + 'autoload': 'all' + } + } + } + + configuration_prerequisites_direct = { + 'enable': ['tcl'], + 'tcl': { + 'all': { + 'prerequisites': 'direct' + } + } + } + + configuration_prerequisites_all = { + 'enable': ['tcl'], + 'tcl': { + 'all': { + 'prerequisites': 'all' + } + } + } + + configuration_alter_environment = { + 'enable': ['tcl'], + 'tcl': { + 'all': { + 'filter': {'environment_blacklist': ['CMAKE_PREFIX_PATH']}, + 'environment': { + 'set': {'{name}_ROOT': '{prefix}'} + } + }, + 'platform=test target=x86_64': { + 'environment': { + 'set': {'FOO': 'foo'}, + 'unset': ['BAR'] + } + }, + 'platform=test target=x86_32': { + 'load': ['foo/bar'] + } + } + } + + configuration_blacklist = { + 'enable': ['tcl'], + 'tcl': { + 'whitelist': ['zmpi'], + 'blacklist': ['callpath', 'mpi'], + 'all': { + 'autoload': 'direct' + } + } + } + + configuration_conflicts = { + 'enable': ['tcl'], + 'tcl': { + 'naming_scheme': '{name}/{version}-{compiler.name}', + 'all': { + 'conflict': ['{name}', 'intel/14.0.1'] + } + } + } + + configuration_wrong_conflicts = { + 'enable': ['tcl'], + 'tcl': { + 'naming_scheme': '{name}/{version}-{compiler.name}', + 'all': { + 'conflict': ['{name}/{compiler.name}'] + } + } + } + + configuration_suffix = { + 'enable': ['tcl'], + 'tcl': { + 'mpileaks': { + 'suffixes': { + '+debug': 'foo', + '~debug': 'bar' + } + } + } + } + def test_simple_case(self): - spack.modules.CONFIGURATION = configuration_autoload_direct - spec = spack.spec.Spec('mpich@3.0.4') + spack.modules.CONFIGURATION = self.configuration_autoload_direct + spec = spack.spec.Spec(mpich_spec_string) content = self.get_modulefile_content(spec) self.assertTrue('module-whatis "mpich @3.0.4"' in content) self.assertRaises(TypeError, spack.modules.dependencies, spec, 'non-existing-tag') def test_autoload(self): - spack.modules.CONFIGURATION = configuration_autoload_direct - spec = spack.spec.Spec('mpileaks') + spack.modules.CONFIGURATION = self.configuration_autoload_direct + spec = spack.spec.Spec(mpileaks_spec_string) content = self.get_modulefile_content(spec) self.assertEqual(len([x for x in content if 'is-loaded' in x]), 2) self.assertEqual(len([x for x in content if 'module load ' in x]), 2) - spack.modules.CONFIGURATION = configuration_autoload_all - spec = spack.spec.Spec('mpileaks') + spack.modules.CONFIGURATION = self.configuration_autoload_all + spec = spack.spec.Spec(mpileaks_spec_string) content = self.get_modulefile_content(spec) self.assertEqual(len([x for x in content if 'is-loaded' in x]), 5) self.assertEqual(len([x for x in content if 'module load ' in x]), 5) @@ -234,7 +251,7 @@ class TclTests(MockPackagesTest): # - 1 ('build','link') dependency # - 1 ('build',) dependency # Just make sure the 'build' dependency is not there - spack.modules.CONFIGURATION = configuration_autoload_direct + spack.modules.CONFIGURATION = self.configuration_autoload_direct spec = spack.spec.Spec('dtbuild1') content = self.get_modulefile_content(spec) self.assertEqual(len([x for x in content if 'is-loaded' in x]), 2) @@ -245,25 +262,25 @@ class TclTests(MockPackagesTest): # - 1 ('build','link') dependency # - 1 ('build',) dependency # Just make sure the 'build' dependency is not there - spack.modules.CONFIGURATION = configuration_autoload_all + spack.modules.CONFIGURATION = self.configuration_autoload_all spec = spack.spec.Spec('dtbuild1') content = self.get_modulefile_content(spec) self.assertEqual(len([x for x in content if 'is-loaded' in x]), 2) self.assertEqual(len([x for x in content if 'module load ' in x]), 2) def test_prerequisites(self): - spack.modules.CONFIGURATION = configuration_prerequisites_direct + spack.modules.CONFIGURATION = self.configuration_prerequisites_direct spec = spack.spec.Spec('mpileaks arch=x86-linux') content = self.get_modulefile_content(spec) self.assertEqual(len([x for x in content if 'prereq' in x]), 2) - spack.modules.CONFIGURATION = configuration_prerequisites_all + spack.modules.CONFIGURATION = self.configuration_prerequisites_all spec = spack.spec.Spec('mpileaks arch=x86-linux') content = self.get_modulefile_content(spec) self.assertEqual(len([x for x in content if 'prereq' in x]), 5) def test_alter_environment(self): - spack.modules.CONFIGURATION = configuration_alter_environment + spack.modules.CONFIGURATION = self.configuration_alter_environment spec = spack.spec.Spec('mpileaks platform=test target=x86_64') content = self.get_modulefile_content(spec) self.assertEqual( @@ -293,7 +310,7 @@ class TclTests(MockPackagesTest): len([x for x in content if 'setenv LIBDWARF_ROOT' in x]), 1) def test_blacklist(self): - spack.modules.CONFIGURATION = configuration_blacklist + spack.modules.CONFIGURATION = self.configuration_blacklist spec = spack.spec.Spec('mpileaks ^zmpi') content = self.get_modulefile_content(spec) self.assertEqual(len([x for x in content if 'is-loaded' in x]), 1) @@ -307,7 +324,7 @@ class TclTests(MockPackagesTest): self.assertEqual(len([x for x in content if 'module load ' in x]), 1) def test_conflicts(self): - spack.modules.CONFIGURATION = configuration_conflicts + spack.modules.CONFIGURATION = self.configuration_conflicts spec = spack.spec.Spec('mpileaks') content = self.get_modulefile_content(spec) self.assertEqual( @@ -317,11 +334,11 @@ class TclTests(MockPackagesTest): self.assertEqual( len([x for x in content if x == 'conflict intel/14.0.1']), 1) - spack.modules.CONFIGURATION = configuration_wrong_conflicts + spack.modules.CONFIGURATION = self.configuration_wrong_conflicts self.assertRaises(SystemExit, self.get_modulefile_content, spec) def test_suffixes(self): - spack.modules.CONFIGURATION = configuration_suffix + spack.modules.CONFIGURATION = self.configuration_suffix spec = spack.spec.Spec('mpileaks+debug arch=x86-linux') spec.concretize() generator = spack.modules.TclModule(spec) @@ -333,18 +350,123 @@ class TclTests(MockPackagesTest): self.assertTrue('bar' in generator.use_name) -configuration_dotkit = { - 'enable': ['dotkit'], - 'dotkit': { - 'all': { - 'prerequisites': 'direct' +class LmodTests(ModuleFileGeneratorTests): + factory = spack.modules.LmodModule + + configuration_autoload_direct = { + 'enable': ['lmod'], + 'lmod': { + 'all': { + 'autoload': 'direct' + } + } + } + + configuration_autoload_all = { + 'enable': ['lmod'], + 'lmod': { + 'all': { + 'autoload': 'all' + } + } + } + + configuration_alter_environment = { + 'enable': ['lmod'], + 'lmod': { + 'all': { + 'filter': {'environment_blacklist': ['CMAKE_PREFIX_PATH']} + }, + 'platform=test target=x86_64': { + 'environment': { + 'set': {'FOO': 'foo'}, + 'unset': ['BAR'] + } + }, + 'platform=test target=x86_32': { + 'load': ['foo/bar'] + } } } -} + + configuration_blacklist = { + 'enable': ['lmod'], + 'lmod': { + 'blacklist': ['callpath'], + 'all': { + 'autoload': 'direct' + } + } + } + + def test_simple_case(self): + spack.modules.CONFIGURATION = self.configuration_autoload_direct + spec = spack.spec.Spec(mpich_spec_string) + content = self.get_modulefile_content(spec) + self.assertTrue('-- -*- lua -*-' in content) + self.assertTrue('whatis([[Name : mpich]])' in content) + self.assertTrue('whatis([[Version : 3.0.4]])' in content) + + def test_autoload(self): + spack.modules.CONFIGURATION = self.configuration_autoload_direct + spec = spack.spec.Spec(mpileaks_spec_string) + content = self.get_modulefile_content(spec) + self.assertEqual( + len([x for x in content if 'if not isloaded(' in x]), 2) + self.assertEqual(len([x for x in content if 'load(' in x]), 2) + + spack.modules.CONFIGURATION = self.configuration_autoload_all + spec = spack.spec.Spec(mpileaks_spec_string) + content = self.get_modulefile_content(spec) + self.assertEqual( + len([x for x in content if 'if not isloaded(' in x]), 5) + self.assertEqual(len([x for x in content if 'load(' in x]), 5) + + def test_alter_environment(self): + spack.modules.CONFIGURATION = self.configuration_alter_environment + spec = spack.spec.Spec('mpileaks platform=test target=x86_64') + content = self.get_modulefile_content(spec) + self.assertEqual( + len([x + for x in content + if x.startswith('prepend_path("CMAKE_PREFIX_PATH"')]), 0) + self.assertEqual( + len([x for x in content if 'setenv("FOO", "foo")' in x]), 1) + self.assertEqual( + len([x for x in content if 'unsetenv("BAR")' in x]), 1) + + spec = spack.spec.Spec('libdwarf %clang platform=test target=x86_32') + content = self.get_modulefile_content(spec) + print('\n'.join(content)) + self.assertEqual( + len([x + for x in content + if x.startswith('prepend-path("CMAKE_PREFIX_PATH"')]), 0) + self.assertEqual( + len([x for x in content if 'setenv("FOO", "foo")' in x]), 0) + self.assertEqual( + len([x for x in content if 'unsetenv("BAR")' in x]), 0) + + def test_blacklist(self): + spack.modules.CONFIGURATION = self.configuration_blacklist + spec = spack.spec.Spec(mpileaks_spec_string) + content = self.get_modulefile_content(spec) + self.assertEqual( + len([x for x in content if 'if not isloaded(' in x]), 1) + self.assertEqual(len([x for x in content if 'load(' in x]), 1) class DotkitTests(MockPackagesTest): + configuration_dotkit = { + 'enable': ['dotkit'], + 'dotkit': { + 'all': { + 'prerequisites': 'direct' + } + } + } + def setUp(self): super(DotkitTests, self).setUp() self.configuration_obj = spack.modules.CONFIGURATION @@ -365,7 +487,7 @@ class DotkitTests(MockPackagesTest): return content def test_dotkit(self): - spack.modules.CONFIGURATION = configuration_dotkit + spack.modules.CONFIGURATION = self.configuration_dotkit spec = spack.spec.Spec('mpileaks arch=x86-linux') content = self.get_modulefile_content(spec) self.assertTrue('#c spack' in content) diff --git a/var/spack/repos/builtin/packages/adios/adios_1100.patch b/var/spack/repos/builtin/packages/adios/adios_1100.patch new file mode 100644 index 0000000000..7a9f857c32 --- /dev/null +++ b/var/spack/repos/builtin/packages/adios/adios_1100.patch @@ -0,0 +1,29 @@ +From 3b21a8a4150962c6938baeceacd04f619cea2fbc Mon Sep 17 00:00:00 2001 +From: Norbert Podhorszki <pnorbert@ornl.gov> +Date: Thu, 1 Sep 2016 16:26:23 -0400 +Subject: [PATCH] ifdef around 'bool' type. hdf5 1.10 defines bool and breaks + compiling bp2h5.c + +--- + utils/bp2h5/bp2h5.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/utils/bp2h5/bp2h5.c b/utils/bp2h5/bp2h5.c +index 9c500c7..fa746bd 100644 +--- a/utils/bp2h5/bp2h5.c ++++ b/utils/bp2h5/bp2h5.c +@@ -43,9 +43,11 @@ + #include "dmalloc.h" + #endif + +-typedef int bool; +-#define false 0 +-#define true 1 ++#ifndef bool ++ typedef int bool; ++# define false 0 ++# define true 1 ++#endif + + bool noindex = false; // do no print array indices with data + bool printByteAsChar = false; // print 8 bit integer arrays as string diff --git a/var/spack/repos/builtin/packages/adios/package.py b/var/spack/repos/builtin/packages/adios/package.py index 01834383b8..e240ce0858 100644 --- a/var/spack/repos/builtin/packages/adios/package.py +++ b/var/spack/repos/builtin/packages/adios/package.py @@ -36,6 +36,8 @@ class Adios(Package): homepage = "http://www.olcf.ornl.gov/center-projects/adios/" url = "https://github.com/ornladios/ADIOS/archive/v1.10.0.tar.gz" + version('develop', git='https://github.com/ornladios/ADIOS.git', + branch='master') version('1.10.0', 'eff450a4c0130479417cfd63186957f3') version('1.9.0', '310ff02388bbaa2b1c1710ee970b5678') @@ -48,14 +50,14 @@ class Adios(Package): variant('mpi', default=True, description='Enable MPI support') variant('infiniband', default=False, description='Enable infiniband support') + # transforms variant('zlib', default=True, description='Enable szip transform support') variant('szip', default=False, description='Enable szip transform support') - variant('hdf5', default=False, description='Enable HDF5 transport support') - variant('netcdf', default=False, description='Enable NetCDF transport support') + # transports and serial file converters + variant('hdf5', default=False, description='Enable parallel HDF5 transport and serial bp2h5 converter') # Lots of setting up here for this package # module swap PrgEnv-intel PrgEnv-$COMP - # module load cray-netcdf/4.3.3.1 # module load cray-hdf5/1.8.14 # module load python/2.7.10 @@ -69,9 +71,13 @@ class Adios(Package): # optional transformations depends_on('zlib', when='+zlib') depends_on('szip', when='+szip') - # optional transports - depends_on('hdf5', when='+hdf5') - depends_on('netcdf', when='+netcdf') + # optional transports & file converters + depends_on('hdf5@1.8:+mpi', when='+hdf5') + + # Fix ADIOS <=1.10.0 compile error on HDF5 1.10+ + # https://github.com/ornladios/ADIOS/commit/3b21a8a41509 + # https://github.com/LLNL/spack/issues/1683 + patch('adios_1100.patch', when='@:1.10.0^hdf5@1.10:') def validate(self, spec): """ @@ -114,9 +120,7 @@ class Adios(Package): if '+szip' in spec: extra_args.append('--with-szip=%s' % spec['szip'].prefix) if '+hdf5' in spec: - extra_args.append('--with-hdf5=%s' % spec['hdf5'].prefix) - if '+netcdf' in spec: - extra_args.append('--with-netcdf=%s' % spec['netcdf'].prefix) + extra_args.append('--with-phdf5=%s' % spec['hdf5'].prefix) sh = which('sh') sh('./autogen.sh') diff --git a/var/spack/repos/builtin/packages/binutils/package.py b/var/spack/repos/builtin/packages/binutils/package.py index af4d87d5c2..bf49ca9405 100644 --- a/var/spack/repos/builtin/packages/binutils/package.py +++ b/var/spack/repos/builtin/packages/binutils/package.py @@ -31,6 +31,7 @@ class Binutils(Package): homepage = "http://www.gnu.org/software/binutils/" url = "https://ftp.gnu.org/gnu/binutils/binutils-2.25.tar.bz2" + version('2.27', '2869c9bf3e60ee97c74ac2a6bf4e9d68') version('2.26', '64146a0faa3b411ba774f47d41de239f') version('2.25', 'd9f3303f802a5b6b0bb73a335ab89d66') version('2.24', 'e0f71a7b2ddab0f8612336ac81d9636b') diff --git a/var/spack/repos/builtin/packages/bpp-suite/package.py b/var/spack/repos/builtin/packages/bpp-suite/package.py index ef7f25a7ce..d15030622e 100644 --- a/var/spack/repos/builtin/packages/bpp-suite/package.py +++ b/var/spack/repos/builtin/packages/bpp-suite/package.py @@ -34,7 +34,6 @@ class BppSuite(Package): version('2.2.0', 'd8b29ad7ccf5bd3a7beb701350c9e2a4') - # FIXME: Add dependencies if required. depends_on('cmake', type='build') depends_on('texinfo', type='build') depends_on('bpp-core') diff --git a/var/spack/repos/builtin/packages/cereal/package.py b/var/spack/repos/builtin/packages/cereal/package.py index 716e0103d1..0ce6ec593c 100644 --- a/var/spack/repos/builtin/packages/cereal/package.py +++ b/var/spack/repos/builtin/packages/cereal/package.py @@ -39,6 +39,7 @@ class Cereal(Package): homepage = "http://uscilab.github.io/cereal/" url = "https://github.com/USCiLab/cereal/archive/v1.1.2.tar.gz" + version('1.2.1', '64476ed74c19068ee543b53ad3992261') version('1.2.0', 'e372c9814696481dbdb7d500e1410d2b') version('1.1.2', '34d4ad174acbff005c36d4d10e48cbb9') version('1.1.1', '0ceff308c38f37d5b5f6df3927451c27') diff --git a/var/spack/repos/builtin/packages/cmake/package.py b/var/spack/repos/builtin/packages/cmake/package.py index 0c16adcef7..83a68fda07 100644 --- a/var/spack/repos/builtin/packages/cmake/package.py +++ b/var/spack/repos/builtin/packages/cmake/package.py @@ -88,11 +88,13 @@ class Cmake(Package): options = [ '--prefix={0}'.format(prefix), - '--parallel={0}'.format(make_jobs), - # jsoncpp requires CMake to build - # use CMake-provided library to avoid circular dependency - '--no-system-jsoncpp' - ] + '--parallel={0}'.format(make_jobs)] + if spec.satisfies("@3:"): + options.append( + # jsoncpp requires CMake to build + # use CMake-provided library to avoid circular dependency + '--no-system-jsoncpp' + ) if '+ownlibs' in spec: # Build and link to the CMake-provided third-party libraries diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py index 052c7a971c..785de08d34 100644 --- a/var/spack/repos/builtin/packages/cp2k/package.py +++ b/var/spack/repos/builtin/packages/cp2k/package.py @@ -53,13 +53,13 @@ class Cp2k(Package): depends_on('plumed+shared+mpi', when='+plumed+mpi') depends_on('plumed+shared~mpi', when='+plumed~mpi') depends_on('pexsi', when='+mpi') + depends_on('wannier90', when='+mpi') + depends_on('elpa', when='+mpi') # TODO : add dependency on libint # TODO : add dependency on libsmm, libxsmm - # TODO : add dependency on elpa # TODO : add dependency on CUDA # TODO : add dependency on QUIP - # TODO : add dependency on libwannier90 parallel = False @@ -109,7 +109,8 @@ class Cp2k(Package): # Add required macro cppflags.extend(['-D__PLUMED2']) libs.extend([ - join_path(self.spec['plumed'].prefix.lib, 'libplumed.so') + join_path(self.spec['plumed'].prefix.lib, + 'libplumed.{0}'.format(dso_suffix)) ]) mkf.write('CC = {0.compiler.cc}\n'.format(self)) @@ -143,15 +144,26 @@ class Cp2k(Package): if '+mpi' in self.spec: cppflags.extend([ '-D__parallel', + '-D__WANNIER90', + '-D__ELPA3', '-D__SCALAPACK' ]) fcflags.extend([ + '-I' + join_path( + spec['elpa'].prefix, + 'include', + 'elpa-{0}'.format(str(spec['elpa'].version)), + 'modules' + ), '-I' + join_path(spec['pexsi'].prefix, 'fortran') ]) ldflags.extend([ '-L' + spec['scalapack'].prefix.lib ]) libs.extend([ + join_path(spec['elpa'].prefix.lib, + 'libelpa.{0}'.format(dso_suffix)), + join_path(spec['wannier90'].prefix.lib, 'libwannier.a'), join_path(spec['pexsi'].prefix.lib, 'libpexsi.a'), join_path(spec['superlu-dist'].prefix.lib, 'libsuperlu_dist.a'), @@ -173,7 +185,8 @@ class Cp2k(Package): '-L' + spec['blas'].prefix.lib ]) libs.extend([ - join_path(spec['fftw'].prefix.lib, 'libfftw3.so'), + join_path(spec['fftw'].prefix.lib, + 'libfftw3.{0}'.format(dso_suffix)), spec['lapack'].lapack_shared_lib, spec['blas'].blas_shared_lib ]) diff --git a/var/spack/repos/builtin/packages/curl/package.py b/var/spack/repos/builtin/packages/curl/package.py index 4954e435c0..a22ac52714 100644 --- a/var/spack/repos/builtin/packages/curl/package.py +++ b/var/spack/repos/builtin/packages/curl/package.py @@ -32,6 +32,8 @@ class Curl(Package): homepage = "http://curl.haxx.se" url = "http://curl.haxx.se/download/curl-7.46.0.tar.bz2" + version('7.50.3', 'bd177fd6deecce00cfa7b5916d831c5e') + version('7.50.2', '6e161179f7af4b9f8b6ea21420132719') version('7.50.1', '015f6a0217ca6f2c5442ca406476920b') version('7.49.1', '6bb1f7af5b58b30e4e6414b8c1abccab') version('7.47.1', '9ea3123449439bbd960cd25cf98796fb') diff --git a/var/spack/repos/builtin/packages/dealii/package.py b/var/spack/repos/builtin/packages/dealii/package.py index 939d8fc013..9e8c639128 100644 --- a/var/spack/repos/builtin/packages/dealii/package.py +++ b/var/spack/repos/builtin/packages/dealii/package.py @@ -32,6 +32,7 @@ class Dealii(Package): homepage = "https://www.dealii.org" url = "https://github.com/dealii/dealii/releases/download/v8.4.1/dealii-8.4.1.tar.gz" + version('8.4.2', '84c6bd3f250d3e0681b645d24cb987a7') version('8.4.1', 'efbaf16f9ad59cfccad62302f36c3c1d') version('8.4.0', 'ac5dbf676096ff61e092ce98c80c2b00') version('8.3.0', 'fc6cdcb16309ef4bea338a4f014de6fa') @@ -67,11 +68,11 @@ class Dealii(Package): # Boost 1.58 is blacklisted, see # https://github.com/dealii/dealii/issues/1591 # Require at least 1.59 - # +python won't affect @:8.4.1 + # +python won't affect @:8.4.2 depends_on("boost@1.59.0:+thread+system+serialization+iostreams", - when='@:8.4.1~mpi') + when='@:8.4.2~mpi') depends_on("boost@1.59.0:+thread+system+serialization+iostreams+mpi", - when='@:8.4.1+mpi') + when='@:8.4.2+mpi') # since @8.5.0: (and @develop) python bindings are introduced: depends_on("boost@1.59.0:+thread+system+serialization+iostreams", when='@8.5.0:~mpi~python') @@ -102,8 +103,8 @@ class Dealii(Package): depends_on("netcdf-cxx", when='+netcdf+mpi') depends_on("oce", when='+oce') depends_on("p4est", when='+p4est+mpi') - depends_on("petsc+mpi", when='@8.5.0:+petsc+mpi') - depends_on("slepc", when='@8.5.0:+slepc+petsc+mpi') + depends_on("petsc+mpi", when='@8.4.2:+petsc+mpi') + depends_on("slepc", when='@8.4.2:+slepc+petsc+mpi') depends_on("petsc@:3.6.4+mpi", when='@:8.4.1+petsc+mpi') depends_on("slepc@:3.6.3", when='@:8.4.1+slepc+petsc+mpi') depends_on("trilinos", when='+trilinos+mpi') diff --git a/var/spack/repos/builtin/packages/elpa/package.py b/var/spack/repos/builtin/packages/elpa/package.py index f28d63f6c3..ae3f26b3ec 100644 --- a/var/spack/repos/builtin/packages/elpa/package.py +++ b/var/spack/repos/builtin/packages/elpa/package.py @@ -34,8 +34,16 @@ class Elpa(Package): homepage = 'http://elpa.mpcdf.mpg.de/' url = 'http://elpa.mpcdf.mpg.de/elpa-2015.11.001.tar.gz' - version('2015.11.001', 'de0f35b7ee7c971fd0dca35c900b87e6', - url='http://elpa.mpcdf.mpg.de/elpa-2015.11.001.tar.gz') + version( + '2016.05.003', + '88a9f3f3bfb63e16509dd1be089dcf2c', + url='http://elpa.mpcdf.mpg.de/html/Releases/2016.05.003/elpa-2016.05.003.tar.gz' + ) + version( + '2015.11.001', + 'de0f35b7ee7c971fd0dca35c900b87e6', + url='http://elpa.mpcdf.mpg.de/elpa-2015.11.001.tar.gz' + ) variant('openmp', default=False, description='Activates OpenMP support') @@ -46,7 +54,12 @@ class Elpa(Package): def install(self, spec, prefix): - options = ["--prefix=%s" % prefix] + options = [ + 'CC={0}'.format(self.spec['mpi'].mpicc), + 'FC={0}'.format(self.spec['mpi'].mpifc), + 'CXX={0}'.format(self.spec['mpi'].mpicxx), + '--prefix={0}'.format(self.prefix) + ] if '+openmp' in spec: options.append("--enable-openmp") diff --git a/var/spack/repos/builtin/packages/gdb/package.py b/var/spack/repos/builtin/packages/gdb/package.py index a14e166ed4..f90e4e7ff0 100644 --- a/var/spack/repos/builtin/packages/gdb/package.py +++ b/var/spack/repos/builtin/packages/gdb/package.py @@ -41,9 +41,18 @@ class Gdb(Package): version('7.9', '8f8ced422fe462a00e0135a643544f17') version('7.8.2', '8b0ea8b3559d3d90b3ff4952f0aeafbc') + variant('python', default=True, description='Compile with Python support') + + # Required dependency depends_on('texinfo', type='build') + # Optional dependency + depends_on('python', when='+python') + def install(self, spec, prefix): - configure('--prefix=%s' % prefix) + options = ['--prefix=%s' % prefix] + if '+python' in spec: + options.extend(['--with-python']) + configure(*options) make() make("install") diff --git a/var/spack/repos/builtin/packages/git-lfs/package.py b/var/spack/repos/builtin/packages/git-lfs/package.py index a080660721..25e440ff6d 100644 --- a/var/spack/repos/builtin/packages/git-lfs/package.py +++ b/var/spack/repos/builtin/packages/git-lfs/package.py @@ -26,17 +26,28 @@ from spack import * class GitLfs(Package): - """Tool for managing large files with Git.""" + """Git LFS is a system for managing and versioning large files in + association with a Git repository. Instead of storing the large files + within the Git repository as blobs, Git LFS stores special "pointer + files" in the repository, while storing the actual file contents on a + Git LFS server.""" homepage = "https://git-lfs.github.com" - url = "https://github.com/github/git-lfs/archive/v1.4.1.tar.gz" + git_url = "https://github.com/github/git-lfs.git" - version('1.4.1', 'c62a314d96d3a30af4d98fa3305ad317') + version('1.4.1', git=git_url, tag='v1.4.1') + version('1.3.1', git=git_url, tag='v1.3.1') + + # TODO: Implement this by following the instructions at this location: + # https://github.com/github/git-lfs/blob/master/CONTRIBUTING.md#building + # variant('test', default=True, description='Build and run tests as part of the build.') # NOQA: E501 depends_on('go@1.5:', type='build') depends_on('git@1.8.2:', type='run') def install(self, spec, prefix): - bootstrap = Executable('./scripts/bootstrap') - bootstrap() - install('bin/git-lfs', prefix.bin) + bootstrap_script = Executable(join_path('script', 'bootstrap')) + bootstrap_script() + + mkdirp(prefix.bin) + install(join_path('bin', 'git-lfs'), prefix.bin) diff --git a/var/spack/repos/builtin/packages/go-bootstrap/package.py b/var/spack/repos/builtin/packages/go-bootstrap/package.py index b0e2109fd3..d48c7c9756 100644 --- a/var/spack/repos/builtin/packages/go-bootstrap/package.py +++ b/var/spack/repos/builtin/packages/go-bootstrap/package.py @@ -1,3 +1,27 @@ +############################################################################## +# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License (as +# published by the Free Software Foundation) version 2.1, February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## import os import shutil import glob @@ -17,25 +41,37 @@ class GoBootstrap(Package): extendable = True - # temporary fix until tags are pulled correctly + # NOTE: Go@1.4.2 is the only supported bootstrapping compiler because all + # later versions require a Go compiler to build. + # See: https://golang.org/doc/install/source version('1.4.2', git='https://go.googlesource.com/go', tag='go1.4.2') - variant('test', - default=True, - description="Run tests as part of build, a good idea but quite" - " time consuming") + variant('test', default=True, description='Build and run tests as part of the build.') provides('golang@:1.4.2') - depends_on('git') + depends_on('git', type='alldeps') + + # NOTE: Older versions of Go attempt to download external files that have + # since been moved while running the test suite. This patch modifies the + # test files so that these tests don't cause false failures. + # See: https://github.com/golang/go/issues/15694 + @when('@:1.4.3') + def patch(self): + test_suite_file = FileFilter(join_path('src', 'run.bash')) + test_suite_file.filter( + r'^(.*)(\$GOROOT/src/cmd/api/run.go)(.*)$', + r'# \1\2\3', + ) + + @when('@1.5.0:') + def patch(self): + pass def install(self, spec, prefix): bash = which('bash') with working_dir('src'): - if '+test' in spec: - bash('all.bash') - else: - bash('make.bash') + bash('{0}.bash'.format('all' if '+test' in spec else 'make')) try: os.makedirs(prefix) diff --git a/var/spack/repos/builtin/packages/go/package.py b/var/spack/repos/builtin/packages/go/package.py index 259498c145..5fa3017ab5 100644 --- a/var/spack/repos/builtin/packages/go/package.py +++ b/var/spack/repos/builtin/packages/go/package.py @@ -1,3 +1,27 @@ +############################################################################## +# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License (as +# published by the Free Software Foundation) version 2.1, February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## import os import shutil import glob @@ -12,28 +36,39 @@ class Go(Package): extendable = True - version('1.5.4', git='https://go.googlesource.com/go', tag='go1.5.4') version('1.6.2', git='https://go.googlesource.com/go', tag='go1.6.2') + version('1.5.4', git='https://go.googlesource.com/go', tag='go1.5.4') + version('1.4.2', git='https://go.googlesource.com/go', tag='go1.4.2') - variant('test', - default=True, - description="Run tests as part of build, a good idea but quite" - " time consuming") + variant('test', default=True, description='Build and run tests as part of the build.') provides('golang') - # to-do, make non-c self-hosting compilers feasible without backflips + depends_on('git', type='alldeps') + # TODO: Make non-c self-hosting compilers feasible without backflips # should be a dep on external go compiler depends_on('go-bootstrap', type='build') - depends_on('git', type='alldeps') + + # NOTE: Older versions of Go attempt to download external files that have + # since been moved while running the test suite. This patch modifies the + # test files so that these tests don't cause false failures. + # See: https://github.com/golang/go/issues/15694 + @when('@:1.4.3') + def patch(self): + test_suite_file = FileFilter(join_path('src', 'run.bash')) + test_suite_file.filter( + r'^(.*)(\$GOROOT/src/cmd/api/run.go)(.*)$', + r'# \1\2\3', + ) + + @when('@1.5.0:') + def patch(self): + pass def install(self, spec, prefix): bash = which('bash') with working_dir('src'): - if '+test' in spec: - bash('all.bash') - else: - bash('make.bash') + bash('{0}.bash'.format('all' if '+test' in spec else 'make')) try: os.makedirs(prefix) diff --git a/var/spack/repos/builtin/packages/grackle/Make.mach.template b/var/spack/repos/builtin/packages/grackle/Make.mach.template new file mode 100644 index 0000000000..83abaa26d1 --- /dev/null +++ b/var/spack/repos/builtin/packages/grackle/Make.mach.template @@ -0,0 +1,71 @@ +MACH_TEXT = Generic Linux +MACH_VALID = 1 +MACH_FILE = Make.mach.@ARCHITECTURE + +#----------------------------------------------------------------------- +# Install paths (local variables) +#----------------------------------------------------------------------- + +LOCAL_HDF5_INSTALL = @HDF5_ROOT + +#----------------------------------------------------------------------- +# Compiler settings +#----------------------------------------------------------------------- + +MACH_CC_NOMPI = @CC # C compiler +MACH_CXX_NOMPI = @CXX # C++ compiler +MACH_FC_NOMPI = @F77 # Fortran 77 +MACH_F90_NOMPI = @FC # Fortran 90 +MACH_LD_NOMPI = @FC # Linker +@LINK_VARIABLES_DEFINITION + +#----------------------------------------------------------------------- +# Machine-dependent defines +#----------------------------------------------------------------------- + +MACH_DEFINES = -DLINUX -DH5_USE_16_API -fPIC + +#----------------------------------------------------------------------- +# Compiler flag settings +#----------------------------------------------------------------------- + +MACH_CPPFLAGS = -P -traditional +MACH_CFLAGS = +MACH_CXXFLAGS = +MACH_FFLAGS = -fno-second-underscore -ffixed-line-length-132 +MACH_F90FLAGS = -fno-second-underscore +MACH_LDFLAGS = @STDCXX_LIB + +#----------------------------------------------------------------------- +# Optimization flags +#----------------------------------------------------------------------- + +MACH_OPT_WARN = -Wall -g +MACH_OPT_DEBUG = -g +MACH_OPT_HIGH = -O2 +MACH_OPT_AGGRESSIVE = -O3 -g + +#----------------------------------------------------------------------- +# Includes +#----------------------------------------------------------------------- + +LOCAL_INCLUDES_HDF5 = -I@HDF5_ROOT/include # HDF5 includes + +MACH_INCLUDES = $(LOCAL_INCLUDES_HDF5) + +#----------------------------------------------------------------------- +# Libraries +#----------------------------------------------------------------------- + +LOCAL_LIBS_HDF5 = -L@HDF5_ROOT/lib -lhdf5 # HDF5 libraries +LOCAL_LIBS_MACH = # Machine-dependent libraries + +MACH_LIBS = $(LOCAL_LIBS_HDF5) $(LOCAL_LIBS_MACH) + +#----------------------------------------------------------------------- +# Installation +#----------------------------------------------------------------------- + +MACH_INSTALL_PREFIX = @PREFIX +MACH_INSTALL_LIB_DIR = +MACH_INSTALL_INCLUDE_DIR = diff --git a/var/spack/repos/builtin/packages/grackle/package.py b/var/spack/repos/builtin/packages/grackle/package.py new file mode 100644 index 0000000000..7e3777158f --- /dev/null +++ b/var/spack/repos/builtin/packages/grackle/package.py @@ -0,0 +1,89 @@ +############################################################################## +# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License (as +# published by the Free Software Foundation) version 2.1, February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## +import os.path +import shutil +import inspect + +from spack import * + + +class Grackle(Package): + """Grackle is a chemistry and radiative cooling library for astrophysical + simulations with interfaces for C, C++, and Fortran codes. It is a + generalized and trimmed down version of the chemistry network of the Enzo + simulation code + """ + homepage = 'http://grackle.readthedocs.io/en/grackle-2.2/' + url = 'https://bitbucket.org/grackle/grackle/get/grackle-2.0.1.tar.bz2' + + version('2.2', 'ec49ed1db5a42db21f478285150c2ba3') + version('2.0.1', 'a9624ad13a60c592c1a0a4ea8e1ae86d') + + depends_on('libtool', when='@2.2') + + depends_on('mpi') + depends_on('hdf5+mpi') + + parallel = False + + def install(self, spec, prefix): + template_name = '{0.architecture}-{0.compiler.name}' + grackle_architecture = template_name.format(spec) + link_variables = 'MACH_AR = ar' if spec.version < Version(2.2) else 'MACH_LIBTOOL = libtool' # NOQA: ignore=E501 + substitutions = { + '@ARCHITECTURE': grackle_architecture, + '@CC': spec['mpi'].mpicc, + '@CXX': spec['mpi'].mpicxx, + '@FC': spec['mpi'].mpifc, + '@F77': spec['mpi'].mpif77, + '@STDCXX_LIB': ' '.join(self.compiler.stdcxx_libs), + '@HDF5_ROOT': spec['hdf5'].prefix, + '@PREFIX': prefix, + '@LINK_VARIABLES_DEFINITION': link_variables + } + + template = join_path( + os.path.dirname(inspect.getmodule(self).__file__), + 'Make.mach.template' + ) + makefile = join_path( + self.stage.source_path, + 'src', + 'clib', + 'Make.mach.{0}'.format(grackle_architecture) + ) + shutil.copy(template, makefile) + for key, value in substitutions.items(): + filter_file(key, value, makefile) + + configure() + with working_dir('src/clib'): + make('clean') + make('machine-{0}'.format(grackle_architecture)) + make('opt-high') + make('show-config') + make() + mkdirp(prefix.lib) + make('install') diff --git a/var/spack/repos/builtin/packages/hwloc/package.py b/var/spack/repos/builtin/packages/hwloc/package.py index c163628840..111c424b22 100644 --- a/var/spack/repos/builtin/packages/hwloc/package.py +++ b/var/spack/repos/builtin/packages/hwloc/package.py @@ -42,6 +42,7 @@ class Hwloc(Package): list_url = "http://www.open-mpi.org/software/hwloc/" list_depth = 3 + version('1.11.4', 'b6f23eb59074fd09fdd84905d50b103d') version('1.11.3', 'c1d36a9de6028eac1d18ea4782ef958f') version('1.11.2', 'e4ca55c2a5c5656da4a4e37c8fc51b23') version('1.11.1', 'feb4e416a1b25963ed565d8b42252fdc') diff --git a/var/spack/repos/builtin/packages/icu/package.py b/var/spack/repos/builtin/packages/icu/package.py index b8d366b905..bf24067879 100644 --- a/var/spack/repos/builtin/packages/icu/package.py +++ b/var/spack/repos/builtin/packages/icu/package.py @@ -31,8 +31,8 @@ class Icu(Package): Globalization support for software applications. ICU is widely portable and gives applications the same results on all platforms.""" - # FIXME: add a proper url for your package's homepage here. - homepage = "http://www.example.com" + + homepage = "http://site.icu-project.org/" url = "http://download.icu-project.org/files/icu4c/54.1/icu4c-54_1-src.tgz" version('54.1', 'e844caed8f2ca24c088505b0d6271bc0') diff --git a/var/spack/repos/builtin/packages/jdk/package.py b/var/spack/repos/builtin/packages/jdk/package.py index 63bf6514cb..bab0920434 100644 --- a/var/spack/repos/builtin/packages/jdk/package.py +++ b/var/spack/repos/builtin/packages/jdk/package.py @@ -68,3 +68,9 @@ class Jdk(Package): def install(self, spec, prefix): distutils.dir_util.copy_tree(".", prefix) + + def setup_environment(self, spack_env, run_env): + run_env.set('JAVA_HOME', self.spec.prefix) + + def setup_dependent_environment(self, spack_env, run_env, dependent_spec): + spack_env.set('JAVA_HOME', self.spec.prefix) diff --git a/var/spack/repos/builtin/packages/julia/package.py b/var/spack/repos/builtin/packages/julia/package.py index 6ccaa11c90..c7c701175e 100644 --- a/var/spack/repos/builtin/packages/julia/package.py +++ b/var/spack/repos/builtin/packages/julia/package.py @@ -37,9 +37,11 @@ class Julia(Package): git='https://github.com/JuliaLang/julia.git', branch='master') version('release-0.5', git='https://github.com/JuliaLang/julia.git', branch='release-0.5') + version('0.5.0', 'b61385671ba74767ab452363c43131fb', preferred=True) version('release-0.4', git='https://github.com/JuliaLang/julia.git', branch='release-0.4') - version('0.4.6', 'd88db18c579049c23ab8ef427ccedf5d', preferred=True) + version('0.4.7', '75a7a7dd882b7840829d8f165e9b9078') + version('0.4.6', 'd88db18c579049c23ab8ef427ccedf5d') version('0.4.5', '69141ff5aa6cee7c0ec8c85a34aa49a6') version('0.4.3', '8a4a59fd335b05090dd1ebefbbe5aaac') @@ -162,7 +164,7 @@ class Julia(Package): # Configure Julia with open(join_path(prefix, "etc", "julia", "juliarc.jl"), "a") as juliarc: - if "@master" in spec or "@release-0.5" in spec: + if "@master" in spec or "@release-0.5" in spec or "@0.5:" in spec: # This is required for versions @0.5: juliarc.write( '# Point package manager to working certificates\n') diff --git a/var/spack/repos/builtin/packages/libuuid/package.py b/var/spack/repos/builtin/packages/libuuid/package.py index 553f0dddb8..b8f6b1cc3a 100644 --- a/var/spack/repos/builtin/packages/libuuid/package.py +++ b/var/spack/repos/builtin/packages/libuuid/package.py @@ -27,7 +27,7 @@ from spack import * class Libuuid(Package): """Portable uuid C library""" - # FIXME: add a proper url for your package's homepage here. + homepage = "http://sourceforge.net/projects/libuuid/" url = "http://downloads.sourceforge.net/project/libuuid/libuuid-1.0.3.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Flibuuid%2F&ts=1433881396&use_mirror=iweb" @@ -36,6 +36,5 @@ class Libuuid(Package): def install(self, spec, prefix): configure("--prefix=%s" % prefix) - # FIXME: Add logic to build and install here make() make("install") diff --git a/var/spack/repos/builtin/packages/llvm/package.py b/var/spack/repos/builtin/packages/llvm/package.py index 61ea8daac4..7582faeb92 100644 --- a/var/spack/repos/builtin/packages/llvm/package.py +++ b/var/spack/repos/builtin/packages/llvm/package.py @@ -22,9 +22,10 @@ # License 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 import * import os +from spack import * + class Llvm(Package): """The LLVM Project is a collection of modular and reusable compiler and @@ -37,9 +38,11 @@ class Llvm(Package): homepage = 'http://llvm.org/' url = 'http://llvm.org/releases/3.7.1/llvm-3.7.1.src.tar.xz' + family = 'compiler' # Used by lmod + # currently required by mesa package version('3.0', 'a8e5f5f1c1adebae7b4a654c376a6005', - url='http://llvm.org/releases/3.0/llvm-3.0.tar.gz') + url='http://llvm.org/releases/3.0/llvm-3.0.tar.gz') # currently required by mesa package variant('debug', default=False, description="Build a debug version of LLVM, this increases " diff --git a/var/spack/repos/builtin/packages/mbedtls/package.py b/var/spack/repos/builtin/packages/mbedtls/package.py index e1a42c0d9a..493ea59f0b 100644 --- a/var/spack/repos/builtin/packages/mbedtls/package.py +++ b/var/spack/repos/builtin/packages/mbedtls/package.py @@ -35,6 +35,7 @@ class Mbedtls(Package): homepage = "https://tls.mbed.org" url = "https://github.com/ARMmbed/mbedtls/archive/mbedtls-2.2.1.tar.gz" + version('2.3.0', '98158e1160a0825a3e8db38881a177a0') version('2.2.1', '73a38f96898d6d03e32f55dd9f9a67be') version('2.2.0', 'eaf4586c1ef93ae872e606b6c1203942') version('2.1.4', '40cdf67b6c6d92c9cbcfd552d39ea3ae') diff --git a/var/spack/repos/builtin/packages/metis/package.py b/var/spack/repos/builtin/packages/metis/package.py index 9f8ed5c9e8..ca48a47817 100644 --- a/var/spack/repos/builtin/packages/metis/package.py +++ b/var/spack/repos/builtin/packages/metis/package.py @@ -43,16 +43,12 @@ class Metis(Package): version('5.0.2', 'acb521a4e8c2e6dd559a7f9abd0468c5') version('4.0.3', 'd3848b454532ef18dc83e4fb160d1e10') - variant('shared', default=True, - description='Enables the build of shared libraries') - variant('debug', default=False, - description='Builds the library in debug mode') - variant('gdb', default=False, description='Enables gdb support') + variant('shared', default=True, description='Enables the build of shared libraries.') + variant('debug', default=False, description='Builds the library in debug mode.') + variant('gdb', default=False, description='Enables gdb support.') - variant('idx64', default=False, - description='Use int64_t as default index type') - variant('real64', default=False, - description='Use double precision floating point types') + variant('idx64', default=False, description='Sets the bit width of METIS\'s index type to 64.') + variant('real64', default=False, description='Sets the bit width of METIS\'s real type to 64.') depends_on('cmake@2.8:', when='@5:', type='build') @@ -63,12 +59,37 @@ class Metis(Package): return '%s/%smetis-%s.tar.gz' % (Metis.base_url, verdir, version) @when('@:4') + def patch(self): + pass + + @when('@5:') + def patch(self): + source_path = self.stage.source_path + metis_header = FileFilter(join_path(source_path, 'include', 'metis.h')) + + metis_header.filter( + r'(\b)(IDXTYPEWIDTH )(\d+)(\b)', + r'\1\2{0}\4'.format('64' if '+idx64' in self.spec else '32'), + ) + metis_header.filter( + r'(\b)(REALTYPEWIDTH )(\d+)(\b)', + r'\1\2{0}\4'.format('64' if '+real64' in self.spec else '32'), + ) + + # Make clang 7.3 happy. + # Prevents "ld: section __DATA/__thread_bss extends beyond end of file" + # See upstream LLVM issue https://llvm.org/bugs/show_bug.cgi?id=27059 + # and https://github.com/Homebrew/homebrew-science/blob/master/metis.rb + if self.spec.satisfies('%clang@7.3.0'): + filter_file('#define MAX_JBUFS 128', '#define MAX_JBUFS 24', + join_path(source_path, 'GKlib', 'error.c')) + + @when('@:4') def install(self, spec, prefix): # Process library spec and options - unsupp_vars = [v for v in ('+gdb', '+idx64', '+real64') if v in spec] - if unsupp_vars: - msg = 'Given variants %s are unsupported by METIS 4!' % unsupp_vars - raise InstallError(msg) + if any('+{0}'.format(v) in spec for v in ['gdb', 'idx64', 'real64']): + raise InstallError('METIS@:4 does not support the following ' + 'variants: gdb, idx64, real64.') options = ['COPTIONS=-fPIC'] if '+debug' in spec: @@ -118,49 +139,48 @@ class Metis(Package): join_path('Programs', 'io.o'), join_path('Test', 'mtest.c'), '-o', '%s/mtest' % prefix.bin, '-lmetis', '-lm') - test_bin = lambda testname: join_path(prefix.bin, testname) - test_graph = lambda graphname: join_path(prefix.share, graphname) - - graph = test_graph('4elt.graph') - os.system('%s %s' % (test_bin('mtest'), graph)) - os.system('%s %s 40' % (test_bin('kmetis'), graph)) - os.system('%s %s' % (test_bin('onmetis'), graph)) - graph = test_graph('test.mgraph') - os.system('%s %s 2' % (test_bin('pmetis'), graph)) - os.system('%s %s 2' % (test_bin('kmetis'), graph)) - os.system('%s %s 5' % (test_bin('kmetis'), graph)) - graph = test_graph('metis.mesh') - os.system('%s %s 10' % (test_bin('partnmesh'), graph)) - os.system('%s %s 10' % (test_bin('partdmesh'), graph)) - os.system('%s %s' % (test_bin('mesh2dual'), graph)) - - # FIXME: The following code should replace the testing code in the - # block above since it causes installs to fail when one or more of the - # Metis tests fail, but it currently doesn't work because the 'mtest', - # 'onmetis', and 'partnmesh' tests return error codes that trigger - # false positives for failure. - """ - Executable(test_bin('mtest'))(test_graph('4elt.graph')) - Executable(test_bin('kmetis'))(test_graph('4elt.graph'), '40') - Executable(test_bin('onmetis'))(test_graph('4elt.graph')) - - Executable(test_bin('pmetis'))(test_graph('test.mgraph'), '2') - Executable(test_bin('kmetis'))(test_graph('test.mgraph'), '2') - Executable(test_bin('kmetis'))(test_graph('test.mgraph'), '5') - - Executable(test_bin('partnmesh'))(test_graph('metis.mesh'), '10') - Executable(test_bin('partdmesh'))(test_graph('metis.mesh'), '10') - Executable(test_bin('mesh2dual'))(test_graph('metis.mesh')) - """ + if self.run_tests: + test_bin = lambda testname: join_path(prefix.bin, testname) + test_graph = lambda graphname: join_path(prefix.share, graphname) + + graph = test_graph('4elt.graph') + os.system('%s %s' % (test_bin('mtest'), graph)) + os.system('%s %s 40' % (test_bin('kmetis'), graph)) + os.system('%s %s' % (test_bin('onmetis'), graph)) + graph = test_graph('test.mgraph') + os.system('%s %s 2' % (test_bin('pmetis'), graph)) + os.system('%s %s 2' % (test_bin('kmetis'), graph)) + os.system('%s %s 5' % (test_bin('kmetis'), graph)) + graph = test_graph('metis.mesh') + os.system('%s %s 10' % (test_bin('partnmesh'), graph)) + os.system('%s %s 10' % (test_bin('partdmesh'), graph)) + os.system('%s %s' % (test_bin('mesh2dual'), graph)) + + # FIXME: The following code should replace the testing code in the + # block above since it causes installs to fail when one or more of + # the Metis tests fail, but it currently doesn't work because the + # 'mtest', 'onmetis', and 'partnmesh' tests return error codes that + # trigger false positives for failure. + """ + Executable(test_bin('mtest'))(test_graph('4elt.graph')) + Executable(test_bin('kmetis'))(test_graph('4elt.graph'), '40') + Executable(test_bin('onmetis'))(test_graph('4elt.graph')) + + Executable(test_bin('pmetis'))(test_graph('test.mgraph'), '2') + Executable(test_bin('kmetis'))(test_graph('test.mgraph'), '2') + Executable(test_bin('kmetis'))(test_graph('test.mgraph'), '5') + + Executable(test_bin('partnmesh'))(test_graph('metis.mesh'), '10') + Executable(test_bin('partdmesh'))(test_graph('metis.mesh'), '10') + Executable(test_bin('mesh2dual'))(test_graph('metis.mesh')) + """ @when('@5:') def install(self, spec, prefix): - options = [] - options.extend(std_cmake_args) - - build_directory = join_path(self.stage.path, 'spack-build') source_directory = self.stage.source_path + build_directory = join_path(source_directory, 'build') + options = std_cmake_args[:] options.append('-DGKLIB_PATH:PATH=%s/GKlib' % source_directory) options.append('-DCMAKE_INSTALL_NAME_DIR:PATH=%s/lib' % prefix) @@ -172,26 +192,24 @@ class Metis(Package): if '+gdb' in spec: options.append('-DGDB:BOOL=ON') - metis_header = join_path(source_directory, 'include', 'metis.h') - if '+idx64' in spec: - filter_file('IDXTYPEWIDTH 32', 'IDXTYPEWIDTH 64', metis_header) - if '+real64' in spec: - filter_file('REALTYPEWIDTH 32', 'REALTYPEWIDTH 64', metis_header) - - # Make clang 7.3 happy. - # Prevents "ld: section __DATA/__thread_bss extends beyond end of file" - # See upstream LLVM issue https://llvm.org/bugs/show_bug.cgi?id=27059 - # and https://github.com/Homebrew/homebrew-science/blob/master/metis.rb - if spec.satisfies('%clang@7.3.0'): - filter_file('#define MAX_JBUFS 128', '#define MAX_JBUFS 24', - join_path(source_directory, 'GKlib', 'error.c')) - with working_dir(build_directory, create=True): cmake(source_directory, *options) make() make('install') - # now run some tests: + # install GKlib headers, which will be needed for ParMETIS + GKlib_dist = join_path(prefix.include, 'GKlib') + mkdirp(GKlib_dist) + hfiles = glob.glob(join_path(source_directory, 'GKlib', '*.h')) + for hfile in hfiles: + install(hfile, GKlib_dist) + + if self.run_tests: + # FIXME: On some systems, the installed binaries for METIS cannot + # be executed without first being read. + ls = which('ls') + ls('-a', '-l', prefix.bin) + for f in ['4elt', 'copter2', 'mdual']: graph = join_path(source_directory, 'graphs', '%s.graph' % f) Executable(join_path(prefix.bin, 'graphchk'))(graph) @@ -202,10 +220,3 @@ class Metis(Package): Executable(join_path(prefix.bin, 'gpmetis'))(graph, '2') graph = join_path(source_directory, 'graphs', 'metis.mesh') Executable(join_path(prefix.bin, 'mpmetis'))(graph, '2') - - # install GKlib headers, which will be needed for ParMETIS - GKlib_dist = join_path(prefix.include, 'GKlib') - mkdirp(GKlib_dist) - hfiles = glob.glob(join_path(source_directory, 'GKlib', '*.h')) - for hfile in hfiles: - install(hfile, GKlib_dist) diff --git a/var/spack/repos/builtin/packages/mvapich2/package.py b/var/spack/repos/builtin/packages/mvapich2/package.py index a123830185..06678bf08b 100644 --- a/var/spack/repos/builtin/packages/mvapich2/package.py +++ b/var/spack/repos/builtin/packages/mvapich2/package.py @@ -28,14 +28,12 @@ from spack import * class Mvapich2(Package): """MVAPICH2 is an MPI implementation for Infiniband networks.""" homepage = "http://mvapich.cse.ohio-state.edu/" - url = "http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.2rc2.tar.gz" + url = "http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.2.tar.gz" - version('2.2rc2', 'f9082ffc3b853ad1b908cf7f169aa878') - version('2.2b', '5651e8b7a72d7c77ca68da48f3a5d108') - version('2.2a', 'b8ceb4fc5f5a97add9b3ff1b9cbe39d2') - version('2.1', '0095ceecb19bbb7fb262131cb9c2cdd6') - version('2.0', '9fbb68a4111a8b6338e476dc657388b4') - version('1.9', '5dc58ed08fd3142c260b70fe297e127c') + version('2.2', '939b65ebe5b89a5bc822cdab0f31f96e') + version('2.1', '0095ceecb19bbb7fb262131cb9c2cdd6') + version('2.0', '9fbb68a4111a8b6338e476dc657388b4') + version('1.9', '5dc58ed08fd3142c260b70fe297e127c') patch('ad_lustre_rwcontig_open_source.patch', when='@1.9') @@ -95,6 +93,7 @@ class Mvapich2(Package): ########## # FIXME : CUDA support is missing + depends_on('bison') depends_on('libpciaccess') def url_for_version(self, version): diff --git a/var/spack/repos/builtin/packages/openblas/package.py b/var/spack/repos/builtin/packages/openblas/package.py index 37f7a7005d..23c7b02daf 100644 --- a/var/spack/repos/builtin/packages/openblas/package.py +++ b/var/spack/repos/builtin/packages/openblas/package.py @@ -32,6 +32,7 @@ class Openblas(Package): homepage = "http://www.openblas.net" url = "http://github.com/xianyi/OpenBLAS/archive/v0.2.15.tar.gz" + version('0.2.19', '28c998054fd377279741c6f0b9ea7941') version('0.2.18', '805e7f660877d588ea7e3792cda2ee65') version('0.2.17', '664a12807f2a2a7cda4781e3ab2ae0e1') version('0.2.16', 'fef46ab92463bdbb1479dcec594ef6dc') diff --git a/var/spack/repos/builtin/packages/openmpi/package.py b/var/spack/repos/builtin/packages/openmpi/package.py index 67bf6f3713..bb356aaccc 100644 --- a/var/spack/repos/builtin/packages/openmpi/package.py +++ b/var/spack/repos/builtin/packages/openmpi/package.py @@ -65,6 +65,7 @@ class Openmpi(Package): list_url = "http://www.open-mpi.org/software/ompi/" list_depth = 3 + version('2.0.1', '6f78155bd7203039d2448390f3b51c96') version('2.0.0', 'cdacc800cb4ce690c1f1273cb6366674') version('1.10.3', 'e2fe4513200e2aaa1500b762342c674b') version('1.10.2', 'b2f43d9635d2d52826e5ef9feb97fd4c') diff --git a/var/spack/repos/builtin/packages/openssl/package.py b/var/spack/repos/builtin/packages/openssl/package.py index 8d9049a8f7..40c8b1b9f1 100644 --- a/var/spack/repos/builtin/packages/openssl/package.py +++ b/var/spack/repos/builtin/packages/openssl/package.py @@ -36,24 +36,18 @@ class Openssl(Package): homepage = "http://www.openssl.org" url = "ftp://openssl.org/source/openssl-1.0.1h.tar.gz" - version('1.0.1h', '8d6d684a9430d5cc98a62a5d8fbda8cf') - version('1.0.1r', '1abd905e079542ccae948af37e393d28') - version('1.0.1t', '9837746fcf8a6727d46d22ca35953da1') - version('1.0.2d', '38dd619b2e77cbac69b99f52a053d25a') - version('1.0.2e', '5262bfa25b60ed9de9f28d5d52d77fc5') - version('1.0.2f', 'b3bf73f507172be9292ea2a8c28b659d') - version('1.0.2g', 'f3c710c045cdee5fd114feb69feba7aa') version('1.0.2h', '9392e65072ce4b614c1392eefc1f23d0') + version('1.0.2g', 'f3c710c045cdee5fd114feb69feba7aa') + version('1.0.2f', 'b3bf73f507172be9292ea2a8c28b659d') + version('1.0.2e', '5262bfa25b60ed9de9f28d5d52d77fc5') + version('1.0.2d', '38dd619b2e77cbac69b99f52a053d25a') + version('1.0.1t', '9837746fcf8a6727d46d22ca35953da1') + version('1.0.1r', '1abd905e079542ccae948af37e393d28') + version('1.0.1h', '8d6d684a9430d5cc98a62a5d8fbda8cf') depends_on("zlib") parallel = False - def url_for_version(self, version): - if '@system' in self.spec: - return '@system (reserved version for system openssl)' - else: - return super(Openssl, self).url_for_version(self.version) - def handle_fetch_error(self, error): tty.warn("Fetching OpenSSL failed. This may indicate that OpenSSL has " "been updated, and the version in your instance of Spack is " diff --git a/var/spack/repos/builtin/packages/parmetis/package.py b/var/spack/repos/builtin/packages/parmetis/package.py index 8afae91af1..74e00cc9e0 100644 --- a/var/spack/repos/builtin/packages/parmetis/package.py +++ b/var/spack/repos/builtin/packages/parmetis/package.py @@ -38,11 +38,9 @@ class Parmetis(Package): version('4.0.3', 'f69c479586bf6bb7aff6a9bc0c739628') version('4.0.2', '0912a953da5bb9b5e5e10542298ffdce') - variant('shared', default=True, - description='Enables the build of shared libraries') - variant('debug', default=False, - description='Builds the library in debug mode') - variant('gdb', default=False, description='Enables gdb support') + variant('shared', default=True, description='Enables the build of shared libraries.') + variant('debug', default=False, description='Builds the library in debug mode.') + variant('gdb', default=False, description='Enables gdb support.') depends_on('cmake@2.8:', type='build') depends_on('mpi') @@ -50,9 +48,9 @@ class Parmetis(Package): patch('enable_external_metis.patch') # bug fixes from PETSc developers - # https://bitbucket.org/petsc/pkg-parmetis/commits/1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b/raw/ + # https://bitbucket.org/petsc/pkg-parmetis/commits/1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b/raw/ # NOQA: E501 patch('pkg-parmetis-1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b.patch') - # https://bitbucket.org/petsc/pkg-parmetis/commits/82409d68aa1d6cbc70740d0f35024aae17f7d5cb/raw/ + # https://bitbucket.org/petsc/pkg-parmetis/commits/82409d68aa1d6cbc70740d0f35024aae17f7d5cb/raw/ # NOQA: E501 patch('pkg-parmetis-82409d68aa1d6cbc70740d0f35024aae17f7d5cb.patch') def url_for_version(self, version): @@ -60,12 +58,10 @@ class Parmetis(Package): return '%s/%sparmetis-%s.tar.gz' % (Parmetis.base_url, verdir, version) def install(self, spec, prefix): - options = [] - options.extend(std_cmake_args) - - build_directory = join_path(self.stage.path, 'spack-build') source_directory = self.stage.source_path + build_directory = join_path(source_directory, 'build') + options = std_cmake_args[:] options.extend([ '-DGKLIB_PATH:PATH=%s/GKlib' % spec['metis'].prefix.include, '-DMETIS_PATH:PATH=%s' % spec['metis'].prefix, diff --git a/var/spack/repos/builtin/packages/petsc/package.py b/var/spack/repos/builtin/packages/petsc/package.py index 73091bb182..1f1b9adffd 100644 --- a/var/spack/repos/builtin/packages/petsc/package.py +++ b/var/spack/repos/builtin/packages/petsc/package.py @@ -90,6 +90,8 @@ class Petsc(Package): def mpi_dependent_options(self): if '~mpi' in self.spec: compiler_opts = [ + '--with-cpp=cpp', + '--with-cxxcpp=cpp', '--with-cc=%s' % os.environ['CC'], '--with-cxx=%s' % (os.environ['CXX'] if self.compiler.cxx is not None else '0'), @@ -111,6 +113,8 @@ class Petsc(Package): raise RuntimeError('\n'.join(errors)) else: compiler_opts = [ + '--with-cpp=cpp', + '--with-cxxcpp=cpp', '--with-mpi=1', '--with-mpi-dir=%s' % self.spec['mpi'].prefix, ] diff --git a/var/spack/repos/builtin/packages/py-beautifulsoup4/package.py b/var/spack/repos/builtin/packages/py-beautifulsoup4/package.py index 64368fe70d..d3a260bd7f 100644 --- a/var/spack/repos/builtin/packages/py-beautifulsoup4/package.py +++ b/var/spack/repos/builtin/packages/py-beautifulsoup4/package.py @@ -37,5 +37,7 @@ class PyBeautifulsoup4(Package): extends('python') + depends_on('py-setuptools', type='build') + def install(self, spec, prefix): python('setup.py', 'install', '--prefix={0}'.format(prefix)) diff --git a/var/spack/repos/builtin/packages/py-proj/package.py b/var/spack/repos/builtin/packages/py-proj/package.py new file mode 100644 index 0000000000..2835bfcca8 --- /dev/null +++ b/var/spack/repos/builtin/packages/py-proj/package.py @@ -0,0 +1,52 @@ +############################################################################## +# Copyright (c) 2016, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Written by David Beckingsale, david@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License (as published by +# the Free Software Foundation) version 2.1 dated February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# 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 import * + + +class PyProj(Package): + """Python interface to the PROJ.4 Library.""" + homepage = "http://jswhit.github.io/pyproj/" + url = "https://github.com/jswhit/pyproj/tarball/v1.9.5.1rel" + + # This is not a tagged release of pyproj. + # The changes in this "version" fix some bugs, especially with Python3 use. + version('1.9.5.1.1', 'd035e4bc704d136db79b43ab371b27d2', + url='https://www.github.com/jswhit/pyproj/tarball/0be612cc9f972e38b50a90c946a9b353e2ab140f') + + version('1.9.5.1', 'a4b80d7170fc82aee363d7f980279835') + + extends('python') + + depends_on('py-cython', type='build') + depends_on('py-setuptools', type='build') + + # NOTE: py-proj does NOT depends_on('proj'). + # The py-proj git repo actually includes the correct version of PROJ.4, + # which is built internally as part of the py-proj build. + # Adding depends_on('proj') will cause mysterious build errors. + + def install(self, spec, prefix): + setup_py('install', '--prefix=%s' % prefix) diff --git a/var/spack/repos/builtin/packages/py-py2neo/package.py b/var/spack/repos/builtin/packages/py-py2neo/package.py index a79c2e477b..97632493af 100644 --- a/var/spack/repos/builtin/packages/py-py2neo/package.py +++ b/var/spack/repos/builtin/packages/py-py2neo/package.py @@ -27,9 +27,10 @@ from spack import Package class PyPy2neo(Package): - """FIXME: put a proper description of your package here.""" - # FIXME: add a proper url for your package's homepage here. - homepage = "http://www.example.com" + """Py2neo is a client library and toolkit for working with Neo4j from + within Python applications and from the command line.""" + + homepage = "http://py2neo.org/" url = "https://github.com/nigelsmall/py2neo/archive/py2neo-2.0.8.tar.gz" version('2.0.8', 'e3ec5172a9e006515ef4155688a05a55') diff --git a/var/spack/repos/builtin/packages/py-yt/package.py b/var/spack/repos/builtin/packages/py-yt/package.py new file mode 100644 index 0000000000..646bd4db2f --- /dev/null +++ b/var/spack/repos/builtin/packages/py-yt/package.py @@ -0,0 +1,78 @@ +############################################################################## +# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License (as +# published by the Free Software Foundation) version 2.1, February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License 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 import * + + +class PyYt(Package): + """Volumetric Data Analysis + + yt is a python package for analyzing and visualizing + volumetric, multi-resolution data from astrophysical + simulations, radio telescopes, and a burgeoning + interdisciplinary community. + """ + homepage = "http://yt-project.org" + url = "https://bitbucket.org/yt_analysis/yt" + + version("3.3.1", hg="https://bitbucket.org/yt_analysis/yt", + tag="yt-3.3.1", commit="9bc3d0e9b750c923d44d73c447df64fc431f5838") + version("3.2.3", hg="https://bitbucket.org/yt_analysis/yt", + tag="yt-3.2.3", commit="83d2c1e9313e7d83eb5b96888451ff2646fd8ff3") + version("3.1.0", hg="https://bitbucket.org/yt_analysis/yt", + tag="yt-3.1.0", commit="fd7cdc4836188a3badf81adb477bcc1b9632e485") + version("3.0.2", hg="https://bitbucket.org/yt_analysis/yt", + tag="yt-3.0.2", commit="511887af4c995a78fe606e58ce8162c88380ecdc") + version("2.6.3", hg="https://bitbucket.org/yt_analysis/yt", + tag="yt-2.6.3", commit="816186f16396a16853810ac9ebcde5057d8d5b1a") + version("development", hg="https://bitbucket.org/yt_analysis/yt", + branch="yt") + + variant("astropy", default=True, description="enable astropy support") + variant("h5py", default=True, description="enable h5py support") + variant("scipy", default=True, description="enable scipy support") + + extends("python") + + depends_on("py-astropy", type="nolink", when="+astropy") + depends_on("py-cython", type="nolink") + depends_on("py-h5py", type="nolink", when="+h5py") + depends_on("py-ipython", type="nolink") + depends_on("py-matplotlib", type="nolink") + depends_on("py-numpy", type="nolink") + depends_on("py-scipy", type="nolink", when="+scipy") + depends_on("py-setuptools", type="build") + depends_on("py-sympy", type="nolink") + depends_on("python @2.7:2.999,3.4:") + + def install(self, spec, prefix): + setup_py("install", "--prefix=%s" % prefix) + self.check_install(spec, prefix) + + def check_install(self, spec, prefix): + # The Python interpreter path can be too long for this + # yt = Executable(join_path(prefix.bin, "yt")) + # yt("--help") + python(join_path(prefix.bin, "yt"), "--help") diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py index 57783b0542..e95bb4ba24 100644 --- a/var/spack/repos/builtin/packages/python/package.py +++ b/var/spack/repos/builtin/packages/python/package.py @@ -110,6 +110,8 @@ class Python(Package): 'CPPFLAGS=-I{0}'.format(' -I'.join(dp.include for dp in dep_pfxs)), 'LDFLAGS=-L{0}'.format(' -L'.join(dp.lib for dp in dep_pfxs)), ] + if spec.satisfies("platform=darwin") and ('%gcc' in spec): + config_args.append('--disable-toolbox-glue') if '+ucs4' in spec: if spec.satisfies('@:2.7'): diff --git a/var/spack/repos/builtin/packages/qt/package.py b/var/spack/repos/builtin/packages/qt/package.py index 436702fa4e..0534c43a7c 100644 --- a/var/spack/repos/builtin/packages/qt/package.py +++ b/var/spack/repos/builtin/packages/qt/package.py @@ -47,6 +47,7 @@ class Qt(Package): variant('krellpatch', default=False, description="Build with openspeedshop based patch.") variant('mesa', default=False, description="Depend on mesa.") variant('gtk', default=False, description="Build with gtkplus.") + variant('examples', default=False, description="Build examples.") patch('qt3krell.patch', when='@3.3.8b+krellpatch') @@ -143,7 +144,7 @@ class Qt(Package): @property def common_config_args(self): - return [ + common_arg_list = [ '-prefix', self.prefix, '-v', '-opensource', @@ -160,6 +161,11 @@ class Qt(Package): '-no-nis' ] + if '~examples' in self.spec: + common_arg_list.extend(['-nomake', 'examples']) + + return common_arg_list + # Don't disable all the database drivers, but should # really get them into spack at some point. diff --git a/var/spack/repos/builtin/packages/samtools/package.py b/var/spack/repos/builtin/packages/samtools/package.py index 6b0b224785..b82a7e55d6 100644 --- a/var/spack/repos/builtin/packages/samtools/package.py +++ b/var/spack/repos/builtin/packages/samtools/package.py @@ -42,7 +42,8 @@ class Samtools(Package): def install(self, spec, prefix): if self.spec.version >= Version('1.3.1'): - configure('--prefix={0}'.format(prefix), '--with-ncurses') + configure('--prefix={0}'.format(prefix), '--with-ncurses', + 'CURSES_LIB=-lncurses') make() make('install') else: diff --git a/var/spack/repos/builtin/packages/silo/package.py b/var/spack/repos/builtin/packages/silo/package.py index 5113c88bdf..691d53a9f1 100644 --- a/var/spack/repos/builtin/packages/silo/package.py +++ b/var/spack/repos/builtin/packages/silo/package.py @@ -41,7 +41,8 @@ class Silo(Package): variant('silex', default=False, description='Builds Silex, a GUI for viewing Silo files') - depends_on('hdf5') + # silo uses the obsolete function H5Pset_fapl_mpiposix: + depends_on("hdf5 @:1.8.12") depends_on('qt', when='+silex') def install(self, spec, prefix): diff --git a/var/spack/repos/builtin/packages/stat/package.py b/var/spack/repos/builtin/packages/stat/package.py index 8c4663c524..eae4971ace 100644 --- a/var/spack/repos/builtin/packages/stat/package.py +++ b/var/spack/repos/builtin/packages/stat/package.py @@ -34,8 +34,8 @@ class Stat(Package): version('2.2.0', '26bd69dd57a15afdd5d0ebdb0b7fb6fc') version('2.1.0', 'ece26beaf057aa9134d62adcdda1ba91') version('2.0.0', 'c7494210b0ba26b577171b92838e1a9b') - version('3.0.0b', '8851912ba40e31cf7be6dde3be8e702c', - url='https://github.com/LLNL/STAT/files/427762/STAT-3.0.0b.tar.gz') + version('3.0.0', 'a97cb235c266371c4a26329112de48a2', + url='https://github.com/LLNL/STAT/releases/download/v3.0.0/STAT-3.0.0.tar.gz') # TODO: dysect requires Dyninst patch for version 3.0.0b variant('dysect', default=False, description="enable DySectAPI") diff --git a/var/spack/repos/builtin/packages/uberftp/package.py b/var/spack/repos/builtin/packages/uberftp/package.py new file mode 100644 index 0000000000..b1b7dada6f --- /dev/null +++ b/var/spack/repos/builtin/packages/uberftp/package.py @@ -0,0 +1,44 @@ +############################################################################## +# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License (as +# published by the Free Software Foundation) version 2.1, February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License 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 import * + + +class Uberftp(Package): + """UberFTP is an interactive (text-based) client for GridFTP""" + + homepage = "http://toolkit.globus.org/grid_software/data/uberftp.php" + url = "https://github.com/JasonAlt/UberFTP/archive/Version_2_8.tar.gz" + + version('2_8', 'bc7a159955a9c4b9f5f42f3d2b8fc830') + version('2_7', 'faaea2d6e1958c1105cfc9147824e03c') + version('2_6', '784210976f259f9d19c0798c19778d34') + + depends_on('globus_toolkit') + + def install(self, spec, prefix): + configure('--prefix={0}'.format(prefix)) + + make() + make('install') diff --git a/var/spack/repos/builtin/packages/visit/package.py b/var/spack/repos/builtin/packages/visit/package.py index d88caeb00a..5d2ab24cc5 100644 --- a/var/spack/repos/builtin/packages/visit/package.py +++ b/var/spack/repos/builtin/packages/visit/package.py @@ -31,13 +31,15 @@ class Visit(Package): homepage = "https://wci.llnl.gov/simulation/computer-codes/visit/" url = "http://portal.nersc.gov/project/visit/releases/2.10.1/visit2.10.1.tar.gz" - version('2.10.1', '3cbca162fdb0249f17c4456605c4211e') + version('2.10.3', 'a1082a6f6dab3e2dcb58993603456c2b') version('2.10.2', '253de0837a9d69fb689befc98ea4d068') + version('2.10.1', '3cbca162fdb0249f17c4456605c4211e') depends_on("vtk@6.1.0~opengl2") depends_on("qt@4.8.6") depends_on("python") depends_on("silo+shared") + depends_on("hdf5~mpi") def install(self, spec, prefix): with working_dir('spack-build', create=True): @@ -46,6 +48,7 @@ class Visit(Package): feature_args.extend([ "-DVTK_MAJOR_VERSION=6", "-DVTK_MINOR_VERSION=1", + "-DVISIT_USE_GLEW=OFF", "-DVISIT_LOC_QMAKE_EXE:FILEPATH=%s/qmake-qt4" % spec[ 'qt'].prefix.bin, "-DPYTHON_EXECUTABLE:FILEPATH=%s/python" % spec[ diff --git a/var/spack/repos/builtin/packages/vtk/gcc.patch b/var/spack/repos/builtin/packages/vtk/gcc.patch new file mode 100644 index 0000000000..37ba5ac45a --- /dev/null +++ b/var/spack/repos/builtin/packages/vtk/gcc.patch @@ -0,0 +1,21 @@ +--- old/CMake/vtkCompilerExtras.cmake ++++ new/CMake/vtkCompilerExtras.cmake +@@ -26,6 +26,8 @@ + execute_process(COMMAND ${CMAKE_C_COMPILER} --version + OUTPUT_VARIABLE _gcc_version_info + ERROR_VARIABLE _gcc_version_info) ++ ++ string (REPLACE ";" "" _gcc_version_info "${_gcc_version_info}") + + string (REGEX MATCH "[345]\\.[0-9]\\.[0-9]" + _gcc_version "${_gcc_version_info}") +--- old/CMake/GenerateExportHeader.cmake ++++ new/CMake/GenerateExportHeader.cmake +@@ -166,6 +166,7 @@ + execute_process(COMMAND ${CMAKE_C_COMPILER} --version + OUTPUT_VARIABLE _gcc_version_info + ERROR_VARIABLE _gcc_version_info) ++ string (REPLACE ";" "" _gcc_version_info "${_gcc_version_info}") + string(REGEX MATCH "[345]\\.[0-9]\\.[0-9]" + _gcc_version "${_gcc_version_info}") + # gcc on mac just reports: "gcc (GCC) 3.3 20030304 ..." without the diff --git a/var/spack/repos/builtin/packages/vtk/package.py b/var/spack/repos/builtin/packages/vtk/package.py index 087c0e93eb..f7015904b0 100644 --- a/var/spack/repos/builtin/packages/vtk/package.py +++ b/var/spack/repos/builtin/packages/vtk/package.py @@ -40,6 +40,8 @@ class Vtk(Package): version('6.1.0', '25e4dfb3bad778722dcaec80cd5dab7d') + patch("gcc.patch") + depends_on('cmake', type='build') depends_on("qt") diff --git a/var/spack/repos/builtin/packages/wannier90/make.sys b/var/spack/repos/builtin/packages/wannier90/make.sys new file mode 100644 index 0000000000..f96fa23fb2 --- /dev/null +++ b/var/spack/repos/builtin/packages/wannier90/make.sys @@ -0,0 +1,7 @@ +F90 = @F90 +COMMS=mpi +MPIF90=@MPIF90 +FCOPTS=-O2 -fpic +LDOPTS=-O2 -fpic + +LIBS = @LIBS diff --git a/var/spack/repos/builtin/packages/wannier90/package.py b/var/spack/repos/builtin/packages/wannier90/package.py new file mode 100644 index 0000000000..189e568cdc --- /dev/null +++ b/var/spack/repos/builtin/packages/wannier90/package.py @@ -0,0 +1,117 @@ +############################################################################## +# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License (as +# published by the Free Software Foundation) version 2.1, February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## +import inspect +import os.path +import shutil + +from spack import * + + +class Wannier90(Package): + """Wannier90 calculates maximally-localised Wannier functions (MLWFs). + + Wannier90 is released under the GNU General Public License. + """ + homepage = 'http://wannier.org' + url = 'http://wannier.org/code/wannier90-2.0.1.tar.gz' + + version('2.0.1', '4edd742506eaba93317249d33261fb22') + + depends_on('mpi') + depends_on('lapack') + depends_on('blas') + + parallel = False + + def install(self, spec, prefix): + + substitutions = { + '@F90': spack_fc, + '@MPIF90': self.spec['mpi'].mpifc, + '@LIBS': ' '.join([ + self.spec['lapack'].lapack_shared_lib, + self.spec['lapack'].blas_shared_lib + ]) + } + ####### + # TODO : this part is replicated in PEXSI + # TODO : and may be a common pattern for Editable Makefiles + # TODO : see #1186 + template = join_path( + os.path.dirname(inspect.getmodule(self).__file__), + 'make.sys' + ) + makefile = join_path( + self.stage.source_path, + 'make.sys' + ) + + shutil.copy(template, makefile) + for key, value in substitutions.items(): + filter_file(key, value, makefile) + ###### + + make('wannier') + mkdirp(self.prefix.bin) + install( + join_path(self.stage.source_path, 'wannier90.x'), + join_path(self.prefix.bin, 'wannier90.x') + ) + + make('post') + install( + join_path(self.stage.source_path, 'postw90.x'), + join_path(self.prefix.bin, 'postw90.x') + ) + + make('lib') + mkdirp(self.prefix.lib) + install( + join_path(self.stage.source_path, 'libwannier.a'), + join_path(self.prefix.lib, 'libwannier.a') + ) + + make('w90chk2chk') + install( + join_path(self.stage.source_path, 'w90chk2chk.x'), + join_path(self.prefix.bin, 'w90chk2chk.x') + ) + + make('w90vdw') + install( + join_path(self.stage.source_path, 'utility', 'w90vdw', 'w90vdw.x'), + join_path(self.prefix.bin, 'w90vdw.x') + ) + + make('w90pov') + install( + join_path(self.stage.source_path, 'utility', 'w90pov', 'w90pov'), + join_path(self.prefix.bin, 'w90pov') + ) + + install_tree( + join_path(self.stage.source_path, 'pseudo'), + join_path(self.prefix.bin, 'pseudo') + ) diff --git a/var/spack/repos/builtin/packages/xorg-util-macros/package.py b/var/spack/repos/builtin/packages/xorg-util-macros/package.py index cd50d46826..3cfc4c2408 100644 --- a/var/spack/repos/builtin/packages/xorg-util-macros/package.py +++ b/var/spack/repos/builtin/packages/xorg-util-macros/package.py @@ -28,7 +28,7 @@ from spack import * class XorgUtilMacros(Package): """The m4 macros used by all of the Xorg packages.""" - homepage = "http://www.example.com" + homepage = "https://cgit.freedesktop.org/xorg/util/macros/" url = "http://ftp.x.org/pub/individual/util/util-macros-1.19.0.tar.bz2" version('1.19.0', '1cf984125e75f8204938d998a8b6c1e1') diff --git a/var/spack/repos/builtin/packages/zoltan/package.py b/var/spack/repos/builtin/packages/zoltan/package.py index 0094395968..8d4dd321b0 100644 --- a/var/spack/repos/builtin/packages/zoltan/package.py +++ b/var/spack/repos/builtin/packages/zoltan/package.py @@ -22,10 +22,11 @@ # License 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 import * import re import os import glob -from spack import * class Zoltan(Package): @@ -47,23 +48,28 @@ class Zoltan(Package): version('3.6', '9cce794f7241ecd8dbea36c3d7a880f9') version('3.3', '5eb8f00bda634b25ceefa0122bd18d65') - variant('debug', default=False, - description='Builds a debug version of the library') - variant('shared', default=True, - description='Builds a shared version of the library') + variant('debug', default=False, description='Builds a debug version of the library.') + variant('shared', default=True, description='Builds a shared version of the library.') - variant('fortran', default=True, description='Enable Fortran support') - variant('mpi', default=False, description='Enable MPI support') + variant('fortran', default=True, description='Enable Fortran support.') + variant('mpi', default=True, description='Enable MPI support.') depends_on('mpi', when='+mpi') + def url_for_version(self, version): + return '%s/zoltan_distrib_v%s.tar.gz' % (Zoltan.base_url, version) + def install(self, spec, prefix): - config_args = [ - '--enable-f90interface' - if '+fortan' in spec else '--disable-f90interface', + # FIXME: The older Zoltan versions fail to compile the F90 MPI wrappers + # because of some complicated generic type problem. + if spec.satisfies('@:3.6+fortran+mpi'): + raise RuntimeError(('Cannot build Zoltan v{0} with +fortran and ' + '+mpi; please disable one of these features ' + 'or upgrade versions.').format(self.version)) - '--enable-mpi' - if '+mpi' in spec else '--disable-mpi', + config_args = [ + self.get_config_flag('f90interface', 'fortran'), + self.get_config_flag('mpi', 'mpi'), ] config_cflags = [ '-O0' if '+debug' in spec else '-O3', @@ -71,49 +77,70 @@ class Zoltan(Package): ] if '+shared' in spec: - config_args.append('--with-ar=$(CXX) -shared $(LDFLAGS) -o') config_args.append('RANLIB=echo') + config_args.append('--with-ar=$(CXX) -shared $(LDFLAGS) -o') config_cflags.append('-fPIC') + if spec.satisfies('%gcc'): + config_args.append('--with-libs={0}'.format('-lgfortran')) if '+mpi' in spec: - config_args.append('CC=%s/mpicc' % spec['mpi'].prefix.bin) - config_args.append('CXX=%s/mpicxx' % spec['mpi'].prefix.bin) - config_args.append('--with-mpi=%s' % spec['mpi'].prefix) - config_args.append('--with-mpi-compilers=%s' % - spec['mpi'].prefix.bin) + config_args.append('CC={0}'.format(spec['mpi'].mpicc)) + config_args.append('CXX={0}'.format(spec['mpi'].mpicxx)) + config_args.append('FC={0}'.format(spec['mpi'].mpifc)) + + mpi_libs = ' -l'.join(self.get_mpi_libs()) + config_args.append('--with-mpi={0}'.format(spec['mpi'].prefix)) + config_args.append('--with-mpi-libs=-l{0}'.format(mpi_libs)) # NOTE: Early versions of Zoltan come packaged with a few embedded # library packages (e.g. ParMETIS, Scotch), which messes with Spack's # ability to descend directly into the package's source directory. + source_directory = self.stage.source_path if spec.satisfies('@:3.6'): - cd('Zoltan_v%s' % self.version) - - mkdirp('build') - cd('build') - - config_zoltan = Executable('../configure') - config_zoltan( - '--prefix=%s' % pwd(), - '--with-cflags=%s' % ' '.join(config_cflags), - '--with-cxxflags=%s' % ' '.join(config_cflags), - *config_args) - - make() - make('install') + zoltan_directory = 'Zoltan_v{0}'.format(self.version) + source_directory = join_path(source_directory, zoltan_directory) + + build_directory = join_path(source_directory, 'build') + with working_dir(build_directory, create=True): + config = Executable(join_path(source_directory, 'configure')) + config( + '--prefix={0}'.format(prefix), + '--with-cflags={0}'.format(' '.join(config_cflags)), + '--with-cxxflags={0}'.format(' '.join(config_cflags)), + '--with-fcflags={0}'.format(' '.join(config_cflags)), + *config_args + ) + + # NOTE: Earlier versions of Zoltan cannot be built in parallel + # because they contain nested Makefile dependency bugs. + make(parallel=not spec.satisfies('@:3.6+fortran')) + make('install') # NOTE: Unfortunately, Zoltan doesn't provide any configuration # options for the extension of the output library files, so this # script must change these extensions as a post-processing step. if '+shared' in spec: - for libpath in glob.glob('lib/*.a'): - libdir, libname = (os.path.dirname(libpath), - os.path.basename(libpath)) - move(libpath, os.path.join( - libdir, re.sub(r'\.a$', '.so', libname))) - - mkdirp(prefix) - move('include', prefix) - move('lib', prefix) - - def url_for_version(self, version): - return '%s/zoltan_distrib_v%s.tar.gz' % (Zoltan.base_url, version) + for lib_path in glob.glob(join_path(prefix, 'lib', '*.a')): + lib_static_name = os.path.basename(lib_path) + lib_shared_name = re.sub(r'\.a$', '.{0}'.format(dso_suffix), + lib_static_name) + move(lib_path, join_path(prefix, 'lib', lib_shared_name)) + + def get_config_flag(self, flag_name, flag_variant): + flag_pre = 'en' if '+{0}'.format(flag_variant) in self.spec else 'dis' + return '--{0}able-{1}'.format(flag_pre, flag_name) + + # NOTE: Zoltan assumes that it's linking against an MPI library that can + # be found with '-lmpi,' which isn't the case for many MPI packages. This + # function finds the names of the actual libraries for Zoltan's MPI dep. + def get_mpi_libs(self): + mpi_libs = set() + + for lib_path in glob.glob(join_path(self.spec['mpi'].prefix.lib, '*')): + mpi_lib_match = re.match( + r'^(lib)((\w*)mpi(\w*))\.((a)|({0}))$'.format(dso_suffix), + os.path.basename(lib_path)) + if mpi_lib_match: + mpi_libs.add(mpi_lib_match.group(2)) + + return list(mpi_libs) |