From 2220784eda80546415e39c783785f2435986a08a Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Thu, 26 May 2016 15:22:17 -0500 Subject: Add scons support, .zip support, and Cantera package --- lib/spack/spack/build_environment.py | 3 +- lib/spack/spack/cmd/create.py | 166 ++++++++++++++------- .../repos/builtin/packages/cantera/package.py | 149 ++++++++++++++++++ .../repos/builtin/packages/py-3to2/package.py | 40 +++++ .../repos/builtin/packages/py-unittest2/package.py | 41 +++++ .../builtin/packages/py-unittest2py3k/package.py | 42 ++++++ var/spack/repos/builtin/packages/serf/package.py | 2 - .../repos/builtin/packages/sundials/package.py | 105 ++++++++++++- .../repos/builtin/packages/superlu-mt/package.py | 135 +++++++++++++++++ 9 files changed, 618 insertions(+), 65 deletions(-) create mode 100644 var/spack/repos/builtin/packages/cantera/package.py create mode 100644 var/spack/repos/builtin/packages/py-3to2/package.py create mode 100644 var/spack/repos/builtin/packages/py-unittest2/package.py create mode 100644 var/spack/repos/builtin/packages/py-unittest2py3k/package.py create mode 100644 var/spack/repos/builtin/packages/superlu-mt/package.py diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py index 7c65091d49..c72dc1a4dd 100644 --- a/lib/spack/spack/build_environment.py +++ b/lib/spack/spack/build_environment.py @@ -290,7 +290,7 @@ def set_module_variables_for_package(pkg, module): """Populate the module scope of install() with some useful functions. This makes things easier for package writers. """ - # number of jobs spack will to build with. + # number of jobs spack will build with. jobs = multiprocessing.cpu_count() if not pkg.parallel: jobs = 1 @@ -303,6 +303,7 @@ def set_module_variables_for_package(pkg, module): # TODO: make these build deps that can be installed if not found. m.make = MakeExecutable('make', jobs) m.gmake = MakeExecutable('gmake', jobs) + m.scons = MakeExecutable('scons', jobs) # easy shortcut to os.environ m.env = os.environ diff --git a/lib/spack/spack/cmd/create.py b/lib/spack/spack/cmd/create.py index 41bfa741f6..fa7ffb3923 100644 --- a/lib/spack/spack/cmd/create.py +++ b/lib/spack/spack/cmd/create.py @@ -1,4 +1,3 @@ -_copyright = """\ ############################################################################## # Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. # Produced at the Lawrence Livermore National Laboratory. @@ -23,10 +22,8 @@ _copyright = """\ # 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 string import os -import hashlib import re from ordereddict_backport import OrderedDict @@ -41,16 +38,37 @@ import spack.util.web from spack.spec import Spec from spack.util.naming import * from spack.repository import Repo, RepoError -import spack.util.crypto as crypto from spack.util.executable import which -from spack.stage import Stage description = "Create a new package file from an archive URL" -package_template = string.Template( - _copyright + """ +package_template = string.Template("""\ +############################################################################## +# 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 +############################################################################## # # This is a template package file for Spack. We've put "FIXME" # next to all the things you'll want to change. Once you've handled @@ -68,8 +86,10 @@ package_template = string.Template( # from spack import * + class ${class_name}(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" url = "${url}" @@ -80,12 +100,10 @@ ${versions} # depends_on("foo") def install(self, spec, prefix): - # FIXME: Modify the configure line to suit your build system here. + # FIXME: Modify the installation instructions here ${configure} - - # FIXME: Add logic to build and install here - make() - make("install") + ${build} + ${install} """) @@ -120,39 +138,78 @@ def setup_parser(subparser): class ConfigureGuesser(object): def __call__(self, stage): - """Try to guess the type of build system used by the project, and return - an appropriate configure line. - """ - autotools = "configure('--prefix=%s' % prefix)" - cmake = "cmake('.', *std_cmake_args)" - python = "python('setup.py', 'install', '--prefix=%s' % prefix)" - r = "R('CMD', 'INSTALL', '--library=%s' % self.module.r_lib_dir, '%s' % self.stage.archive_file)" - - config_lines = ((r'/configure$', 'autotools', autotools), - (r'/CMakeLists.txt$', 'cmake', cmake), - (r'/setup.py$', 'python', python), - (r'/NAMESPACE$', 'r', r)) - - # Peek inside the tarball. - tar = which('tar') - output = tar( - "--exclude=*/*/*", "-tf", stage.archive_file, output=str) - lines = output.split("\n") - - # Set the configure line to the one that matched. - for pattern, bs, cl in config_lines: + """Try to guess the type of build system used by the project. Set the + appropriate default configure, build, and install instructions.""" + + # Default configure instructions + configureDict = { + 'autotools': "configure('--prefix={0}'.format(prefix))", + 'cmake': "cmake('.', *std_cmake_args)", + 'scons': "", + 'python': "", + 'r': "", + 'unknown': "# FIXME: Unknown build system" + } + + # Default build instructions + buildDict = { + 'autotools': "make()", + 'cmake': "make()", + 'scons': "scons('prefix={0}'.format(prefix))", + 'python': "", + 'r': "", + 'unknown': "make()", + } + + # Default install instructions + installDict = { + 'autotools': "make('install')", + 'cmake': "make('install')", + 'scons': "scons('install')", + 'python': "python('setup.py', 'install', " + + "'--prefix={0}'.format(prefix))", + 'r': "R('CMD', 'INSTALL', '--library={0}'.format(" + + "self.module.r_lib_dir), self.stage.archive_file)", + 'unknown': "make('install')", + } + + # A list of clues that give us an idea of the build system a package + # uses. If the regular expression matches a file contained in the + # archive, the corresponding build system is assumed. + clues = [ + (r'/configure$', 'autotools'), + (r'/CMakeLists.txt$', 'cmake'), + (r'/SConstruct$', 'scons'), + (r'/setup.py$', 'python'), + (r'/NAMESPACE$', 'r') + ] + + # Peek inside the compressed file. + output = '' + if stage.archive_file.endswith(('.tar', '.tar.gz', '.tar.bz2', + '.tgz', '.tbz2')): + tar = which('tar') + output = tar('--exclude=*/*/*', '-tf', + stage.archive_file, output=str) + elif stage.archive_file.endswith('.gz'): + gunzip = which('gunzip') + output = gunzip('-l', stage.archive_file, output=str) + elif stage.archive_file.endswith('.zip'): + unzip = which('unzip') + output = unzip('-l', stage.archive_file, output=str) + lines = output.split('\n') + + # Determine the build system based on the files contained + # in the archive. + build_system = 'unknown' + for pattern, bs in clues: if any(re.search(pattern, l) for l in lines): - config_line = cl build_system = bs - break - else: - # None matched -- just put both, with cmake commented out - config_line = "# FIXME: Spack couldn't guess one, so here are some options:\n" - config_line += " # " + autotools + "\n" - config_line += " # " + cmake - build_system = 'unknown' - self.configure = config_line + self.configure = configureDict[build_system] + self.build = buildDict[build_system] + self.install = installDict[build_system] + self.build_system = build_system @@ -168,7 +225,7 @@ def guess_name_and_version(url, args): else: try: name = spack.url.parse_name(url, version) - except spack.url.UndetectableNameError, e: + except spack.url.UndetectableNameError: # Use a user-supplied name if one is present tty.die("Couldn't guess a name for this package. Try running:", "", "spack create --name ") @@ -182,7 +239,8 @@ def guess_name_and_version(url, args): def find_repository(spec, args): # figure out namespace for spec if spec.namespace and args.namespace and spec.namespace != args.namespace: - tty.die("Namespaces '%s' and '%s' do not match." % (spec.namespace, args.namespace)) + tty.die("Namespaces '%s' and '%s' do not match." % (spec.namespace, + args.namespace)) if not spec.namespace and args.namespace: spec.namespace = args.namespace @@ -193,8 +251,8 @@ def find_repository(spec, args): try: repo = Repo(repo_path) if spec.namespace and spec.namespace != repo.namespace: - tty.die("Can't create package with namespace %s in repo with namespace %s" - % (spec.namespace, repo.namespace)) + tty.die("Can't create package with namespace %s in repo with " + "namespace %s" % (spec.namespace, repo.namespace)) except RepoError as e: tty.die(str(e)) else: @@ -214,11 +272,7 @@ def find_repository(spec, args): def fetch_tarballs(url, name, version): """Try to find versions of the supplied archive by scraping the web. - - Prompts the user to select how many to download if many are found. - - - """ + Prompts the user to select how many to download if many are found.""" versions = spack.util.web.find_versions_of_archive(url) rkeys = sorted(versions.keys(), reverse=True) versions = OrderedDict(zip(rkeys, (versions[v] for v in rkeys))) @@ -226,11 +280,11 @@ def fetch_tarballs(url, name, version): archives_to_fetch = 1 if not versions: # If the fetch failed for some reason, revert to what the user provided - versions = { version : url } + versions = {version: url} elif len(versions) > 1: tty.msg("Found %s versions of %s:" % (len(versions), name), *spack.cmd.elide_list( - ["%-10s%s" % (v,u) for v, u in versions.iteritems()])) + ["%-10s%s" % (v, u) for v, u in versions.iteritems()])) print archives_to_fetch = tty.get_number( "Include how many checksums in the package file?", @@ -292,10 +346,12 @@ def create(parser, args): pkg_file.write( package_template.substitute( name=name, - configure=guesser.configure, class_name=mod_to_class(name), url=url, - versions=make_version_calls(ver_hash_tuples))) + versions=make_version_calls(ver_hash_tuples), + configure=guesser.configure, + build=guesser.build, + install=guesser.install)) # If everything checks out, go ahead and edit. spack.editor(pkg_path) diff --git a/var/spack/repos/builtin/packages/cantera/package.py b/var/spack/repos/builtin/packages/cantera/package.py new file mode 100644 index 0000000000..a55f883560 --- /dev/null +++ b/var/spack/repos/builtin/packages/cantera/package.py @@ -0,0 +1,149 @@ +############################################################################## +# 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 * +import spack +import os + + +class Cantera(Package): + """Cantera is a suite of object-oriented software tools for problems + involving chemical kinetics, thermodynamics, and/or transport processes.""" + + homepage = "http://www.cantera.org/docs/sphinx/html/index.html" + url = "https://github.com/Cantera/cantera/archive/v2.2.1.tar.gz" + + version('2.2.1', '9d1919bdef39ddec54485fc8a741a3aa') + + variant('lapack', default=True, description='Build with external BLAS/LAPACK libraries') + variant('threadsafe', default=True, description='Build threadsafe, requires Boost') + variant('sundials', default=True, description='Build with external Sundials') + variant('python', default=False, description='Build the Cantera Python module') + variant('matlab', default=False, description='Build the Cantera Matlab toolbox') + + # Required dependencies + depends_on('scons') + + # Recommended dependencies + depends_on('blas', when='+lapack') + depends_on('lapack', when='+lapack') + depends_on('boost', when='+threadsafe') + depends_on('sundials', when='+sundials') # must be compiled with -fPIC + + # Python module dependencies + extends('python', when='+python') + depends_on('py-numpy', when='+python') + depends_on('py-scipy', when='+python') + depends_on('py-cython', when='+python') + depends_on('py-3to2', when='+python') + # TODO: these "when" specs don't actually work + #depends_on('py-unittest2', when='+python^python@2.6') + #depends_on('py-unittest2py3k', when='+python^python@3.1') + + # Matlab toolbox dependencies + # TODO: add Matlab package + # TODO: allow packages to extend multiple other packages + #extends('matlab', when='+matlab') + + def install(self, spec, prefix): + # Required options + options = [ + 'prefix={0}'.format(prefix), + 'CC={0}'.format(os.environ['CC']), + 'CXX={0}'.format(os.environ['CXX']), + 'F77={0}'.format(os.environ['F77']), + 'FORTRAN={0}'.format(os.environ['FC']), + 'cc_flags=-fPIC', + # Allow Spack environment variables to propagate through to SCons + 'env_vars=all' + ] + + # BLAS/LAPACK support + if '+lapack' in spec: + options.extend([ + 'blas_lapack_libs=lapack,blas', + 'blas_lapack_dir={0}'.format(spec['lapack'].prefix.lib) + ]) + + # Threadsafe build, requires Boost + if '+threadsafe' in spec: + options.extend([ + 'build_thread_safe=yes', + 'boost_inc_dir={0}'.format(spec['boost'].prefix.include), + 'boost_lib_dir={0}'.format(spec['boost'].prefix.lib), + 'boost_thread_lib=boost_thread-mt' + ]) + else: + options.append('build_thread_safe=no') + + # Sundials support + if '+sundials' in spec: + options.extend([ + 'use_sundials=y', + 'sundials_include={0}'.format(spec['sundials'].prefix.include), + 'sundials_libdir={0}'.format(spec['sundials'].prefix.lib), + 'sundials_license={0}'.format( + join_path(spec['sundials'].prefix, 'LICENSE')) + ]) + else: + options.append('use_sundials=n') + + # Python module + if '+python' in spec: + options.extend([ + 'python_package=full', + 'python_cmd={0}'.format( + join_path(spec['python'].prefix.bin, 'python')), + 'python_array_home={0}'.format(spec['py-numpy'].prefix) + ]) + if spec['python'].satisfies('@3'): + options.extend([ + 'python3_package=y', + 'python3_cmd={0}'.format( + join_path(spec['python'].prefix.bin, 'python')), + 'python3_array_home={0}'.format(spec['py-numpy'].prefix) + ]) + else: + options.append('python3_package=n') + else: + options.append('python_package=none') + options.append('python3_package=n') + + # Matlab toolbox + if '+matlab' in spec: + options.extend([ + 'matlab_toolbox=y', + 'matlab_path={0}'.format(spec['matlab'].prefix) + ]) + else: + options.append('matlab_toolbox=n') + + scons('build', *options) + + if '+python' in spec: + # Tests will always fail if Python dependencies aren't built + #scons('test') # TODO: 3 expected failures, not sure what's wrong + pass + + scons('install') diff --git a/var/spack/repos/builtin/packages/py-3to2/package.py b/var/spack/repos/builtin/packages/py-3to2/package.py new file mode 100644 index 0000000000..577662e583 --- /dev/null +++ b/var/spack/repos/builtin/packages/py-3to2/package.py @@ -0,0 +1,40 @@ +############################################################################## +# 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 Py3to2(Package): + """lib3to2 is a set of fixers that are intended to backport code written + for Python version 3.x into Python version 2.x.""" + + homepage = "https://pypi.python.org/pypi/3to2" + url = "https://pypi.python.org/packages/8f/ab/58a363eca982c40e9ee5a7ca439e8ffc5243dde2ae660ba1ffdd4868026b/3to2-1.1.1.zip" + + version('1.1.1', 'cbeed28e350dbdaef86111ace3052824') + + extends('python') + + def install(self, spec, prefix): + python('setup.py', 'install', '--prefix=%s' % prefix) diff --git a/var/spack/repos/builtin/packages/py-unittest2/package.py b/var/spack/repos/builtin/packages/py-unittest2/package.py new file mode 100644 index 0000000000..c9b0ad5cdf --- /dev/null +++ b/var/spack/repos/builtin/packages/py-unittest2/package.py @@ -0,0 +1,41 @@ +############################################################################## +# 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 PyUnittest2(Package): + """unittest2 is a backport of the new features added to the unittest + testing framework in Python 2.7 and onwards.""" + + homepage = "https://pypi.python.org/pypi/unittest2" + url = "https://pypi.python.org/packages/7f/c4/2b0e2d185d9d60772c10350d9853646832609d2f299a8300ab730f199db4/unittest2-1.1.0.tar.gz" + + version('1.1.0', 'f72dae5d44f091df36b6b513305ea000') + + extends('python') + depends_on('py-setuptools') + + def install(self, spec, prefix): + python('setup.py', 'install', '--prefix=%s' % prefix) diff --git a/var/spack/repos/builtin/packages/py-unittest2py3k/package.py b/var/spack/repos/builtin/packages/py-unittest2py3k/package.py new file mode 100644 index 0000000000..b2c7510d94 --- /dev/null +++ b/var/spack/repos/builtin/packages/py-unittest2py3k/package.py @@ -0,0 +1,42 @@ +############################################################################## +# 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 PyUnittest2py3k(Package): + """unittest2 is a backport of the new features added to the unittest + testing framework in Python 2.7 and 3.2. This is a Python 3 compatible + version of unittest2.""" + + homepage = "https://pypi.python.org/pypi/unittest2py3k" + url = "https://pypi.python.org/packages/4e/3d/d44421e8d828af1399c1509c196db92e2a58f3764b01a0ee928d7025d1ca/unittest2py3k-0.5.1.tar.gz" + + version('0.5.1', '8824ff92044310d9365f90d892bf0f09') + + extends('python') + depends_on('py-setuptools') + + def install(self, spec, prefix): + python('setup.py', 'install', '--prefix=%s' % prefix) diff --git a/var/spack/repos/builtin/packages/serf/package.py b/var/spack/repos/builtin/packages/serf/package.py index 817db68241..074d3d64b2 100644 --- a/var/spack/repos/builtin/packages/serf/package.py +++ b/var/spack/repos/builtin/packages/serf/package.py @@ -41,8 +41,6 @@ class Serf(Package): depends_on('zlib') def install(self, spec, prefix): - scons = which("scons") - options = ['PREFIX=%s' % prefix] options.append('APR=%s' % spec['apr'].prefix) options.append('APU=%s' % spec['apr-util'].prefix) diff --git a/var/spack/repos/builtin/packages/sundials/package.py b/var/spack/repos/builtin/packages/sundials/package.py index ba2340f74c..a31cf5fde4 100644 --- a/var/spack/repos/builtin/packages/sundials/package.py +++ b/var/spack/repos/builtin/packages/sundials/package.py @@ -24,16 +24,107 @@ ############################################################################## from spack import * + class Sundials(Package): - """SUNDIALS (SUite of Nonlinear and DIfferential/ALgebraic equation Solvers)""" + """SUNDIALS (SUite of Nonlinear and DIfferential/ALgebraic equation + Solvers)""" + homepage = "http://computation.llnl.gov/casc/sundials/" - url = "http://computation.llnl.gov/casc/sundials/download/code/sundials-2.5.0.tar.gz" + url = "http://computation.llnl.gov/projects/sundials-suite-nonlinear-differential-algebraic-equation-solvers/download/sundials-2.6.2.tar.gz" + + version('2.6.2', '3deeb0ede9f514184c6bd83ecab77d95') - version('2.5.0', 'aba8b56eec600de3109cfb967aa3ba0f') + variant('mpi', default=True, description='Enable MPI support') + variant('lapack', default=True, description='Build with external BLAS/LAPACK libraries') + variant('klu', default=True, description='Build with SuiteSparse KLU libraries') + variant('superlu', default=True, description='Build with SuperLU_MT libraries') + variant('openmp', default=False, description='Enable OpenMP support') + variant('pthread', default=True, description='Enable POSIX threads support') - depends_on("mpi") + depends_on('mpi', when='+mpi') + depends_on('blas', when='+lapack') + depends_on('lapack', when='+lapack') + depends_on('suite-sparse', when='+klu') + depends_on('superlu-mt+openmp', when='+superlu+openmp') + depends_on('superlu-mt+pthread', when='+superlu+pthread') def install(self, spec, prefix): - configure("--prefix=%s" % prefix) - make() - make("install") + cmake_args = std_cmake_args + cmake_args.extend([ + '-DBUILD_SHARED_LIBS=ON', + '-DCMAKE_C_FLAGS=-fPIC' + ]) + + # MPI support + if '+mpi' in spec: + cmake_args.extend([ + '-DMPI_ENABLE=ON', + '-DMPI_MPICC={0}'.format(spec['mpi'].mpicc), + '-DMPI_MPIF77={0}'.format(spec['mpi'].mpif77) + ]) + else: + cmake_args.append('-DMPI_ENABLE=OFF') + + # Building with LAPACK and BLAS + if '+lapack' in spec: + cmake_args.extend([ + '-DLAPACK_ENABLE=ON', + '-DLAPACK_LIBRARIES={0};{1}'.format( + spec['lapack'].lapack_shared_lib, + spec['blas'].blas_shared_lib + ) + ]) + else: + cmake_args.append('-DLAPACK_ENABLE=OFF') + + # Building with KLU + if '+klu' in spec: + cmake_args.extend([ + '-DKLU_ENABLE=ON', + '-DKLU_INCLUDE_DIR={0}'.format( + spec['suite-sparse'].prefix.include), + '-DKLU_LIBRARY_DIR={0}'.format( + spec['suite-sparse'].prefix.lib) + ]) + else: + cmake_args.append('-DKLU_ENABLE=OFF') + + # Building with SuperLU_MT + if '+superlu' in spec: + cmake_args.extend([ + '-DSUPERLUMT_ENABLE=ON', + '-DSUPERLUMT_INCLUDE_DIR={0}'.format( + spec['superlu-mt'].prefix.include), + '-DSUPERLUMT_LIBRARY_DIR={0}'.format( + spec['superlu-mt'].prefix.lib) + ]) + if '+openmp' in spec: + cmake_args.append('-DSUPERLUMT_THREAD_TYPE=OpenMP') + elif '+pthread' in spec: + cmake_args.append('-DSUPERLUMT_THREAD_TYPE=Pthread') + else: + msg = 'You must choose either +openmp or +pthread when ' + msg += 'building with SuperLU_MT' + raise RuntimeError(msg) + else: + cmake_args.append('-DSUPERLUMT_ENABLE=OFF') + + # OpenMP support + if '+openmp' in spec: + cmake_args.append('-DOPENMP_ENABLE=ON') + else: + cmake_args.append('-DOPENMP_ENABLE=OFF') + + # POSIX threads support + if '+pthread' in spec: + cmake_args.append('-DPTHREAD_ENABLE=ON') + else: + cmake_args.append('-DPTHREAD_ENABLE=OFF') + + with working_dir('build', create=True): + cmake('..', *cmake_args) + + make() + make('install') + + install('LICENSE', prefix) diff --git a/var/spack/repos/builtin/packages/superlu-mt/package.py b/var/spack/repos/builtin/packages/superlu-mt/package.py new file mode 100644 index 0000000000..5eee4bf5d9 --- /dev/null +++ b/var/spack/repos/builtin/packages/superlu-mt/package.py @@ -0,0 +1,135 @@ +############################################################################## +# 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 * +import spack +import glob +import os + + +class SuperluMt(Package): + """SuperLU is a general purpose library for the direct solution of large, + sparse, nonsymmetric systems of linear equations on high performance + machines. SuperLU_MT is designed for shared memory parallel machines.""" + + homepage = "http://crd-legacy.lbl.gov/~xiaoye/SuperLU/#superlu_mt" + url = "http://crd-legacy.lbl.gov/~xiaoye/SuperLU/superlu_mt_3.1.tar.gz" + + version('3.1', '06ac62f1b4b7d17123fffa0d0c315e91') + + variant('blas', default=True, description='Build with external BLAS library') + + # Must choose one or the other + variant('openmp', default=False, description='Build with OpenMP support') + variant('pthread', default=True, description='Build with POSIX threads support') + + # NOTE: must link with a single-threaded BLAS library + depends_on('blas', when='+blas') + + # Cannot be built in parallel + parallel = False + + def configure(self, spec): + # Validate chosen variants + if '+openmp' in spec and '+pthread' in spec: + msg = 'You cannot choose both +openmp and +pthread' + raise RuntimeError(msg) + if '~openmp' in spec and '~pthread' in spec: + msg = 'You must choose either +openmp or +pthread' + raise RuntimeError(msg) + + # List of configuration options + config = [] + + # The machine (platform) identifier to append to the library names + if '+openmp' in spec: + # OpenMP + config.extend([ + 'PLAT = _OPENMP', + 'TMGLIB = libtmglib.a', + 'MPLIB = {0}'.format(self.compiler.openmp_flag), + 'CFLAGS = {0}'.format(self.compiler.openmp_flag), + 'FFLAGS = {0}'.format(self.compiler.openmp_flag) + ]) + elif '+pthread' in spec: + # POSIX threads + config.extend([ + 'PLAT = _PTHREAD', + 'TMGLIB = libtmglib$(PLAT).a', + 'MPLIB = -lpthread' + ]) + + # The BLAS library + # NOTE: must link with a single-threaded BLAS library + if '+blas' in spec: + config.extend([ + 'BLASDEF = -DUSE_VENDOR_BLAS', + 'BLASLIB = -L{0} -lblas'.format(spec['blas'].prefix.lib) + ]) + else: + config.append('BLASLIB = ../lib/libblas$(PLAT).a') + + # Generic options + config.extend([ + # The name of the libraries to be created/linked to + 'SUPERLULIB = libsuperlu_mt$(PLAT).a', + 'MATHLIB = -lm', + # The archiver and the flag(s) to use when building archives + 'ARCH = ar', + 'ARCHFLAGS = cr', + 'RANLIB = {0}'.format('ranlib' if which('ranlib') else 'echo'), + # Definitions used by CPP + 'PREDEFS = -D_$(PLAT)', + # Compilers and flags + 'CC = {0}'.format(os.environ['CC']), + 'CFLAGS += $(PREDEFS) -D_LONGINT', + 'NOOPTS = -O0', + 'FORTRAN = {0}'.format(os.environ['FC']), + 'LOADER = {0}'.format(os.environ['CC']), + # C preprocessor defs for compilation + 'CDEFS = -DAdd_' + ]) + + # Write configuration options to include file + with open('make.inc', 'w') as inc: + for option in config: + inc.write('{0}\n'.format(option)) + + def install(self, spec, prefix): + # Set up make include file manually + self.configure(spec) + + # BLAS needs to be compiled separately if using internal BLAS library + if '+blas' not in spec: + make('blaslib') + + make() + + # Install manually + install_tree('lib', prefix.lib) + + headers = glob.glob(join_path('SRC', '*.h')) + mkdir(prefix.include) + for h in headers: + install(h, prefix.include) -- cgit v1.2.3-70-g09d2