diff options
author | Saravan Pantham <saravan.pantham@gmail.com> | 2015-04-06 14:03:09 -0700 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2015-06-06 15:26:31 -0700 |
commit | c174fe6199eaa86fccf3fafa9bbfbff6f3385089 (patch) | |
tree | 47f31804065f465f743c72e88a9e52b7ffaa98d0 | |
parent | d461aa3722b5b19acebe9a37bea1739222186755 (diff) | |
download | spack-c174fe6199eaa86fccf3fafa9bbfbff6f3385089.tar.gz spack-c174fe6199eaa86fccf3fafa9bbfbff6f3385089.tar.bz2 spack-c174fe6199eaa86fccf3fafa9bbfbff6f3385089.tar.xz spack-c174fe6199eaa86fccf3fafa9bbfbff6f3385089.zip |
Fixed BLAS and Lapack installations
-rw-r--r-- | lib/spack/llnl/util/filesystem.py | 1 | ||||
-rw-r--r-- | lib/spack/llnl/util/filesystem.py.save | 0 | ||||
-rw-r--r-- | lib/spack/llnl/util/filesystem.py.save.1 | 229 | ||||
-rw-r--r-- | var/spack/packages/blas/package.py | 8 | ||||
-rw-r--r-- | var/spack/packages/lapack/package.py | 15 |
5 files changed, 236 insertions, 17 deletions
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py index 3b34e04740..8eff642938 100644 --- a/lib/spack/llnl/util/filesystem.py +++ b/lib/spack/llnl/util/filesystem.py @@ -40,7 +40,6 @@ from tempfile import NamedTemporaryFile import llnl.util.tty as tty from spack.util.compression import ALLOWED_ARCHIVE_TYPES - def filter_file(regex, repl, *filenames, **kwargs): """Like sed, but uses python regular expressions. diff --git a/lib/spack/llnl/util/filesystem.py.save b/lib/spack/llnl/util/filesystem.py.save new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/spack/llnl/util/filesystem.py.save diff --git a/lib/spack/llnl/util/filesystem.py.save.1 b/lib/spack/llnl/util/filesystem.py.save.1 new file mode 100644 index 0000000000..82cfe965b2 --- /dev/null +++ b/lib/spack/llnl/util/filesystem.py.save.1 @@ -0,0 +1,229 @@ +############################################################################## +# 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 +############################################################################## +__all__ = ['set_install_permissions', 'install', 'expand_user', 'working_dir', + 'touch', 'touchp', 'mkdirp', 'force_remove', 'join_path', 'ancestor', + 'can_access', 'filter_file', 'change_sed_delimiter', 'is_exe'] + +import os +import sys +import re +import shutil +import stat +import errno +import getpass +from contextlib import contextmanager, closing +from tempfile import NamedTemporaryFile + +import llnl.util.tty as tty +from spack.util.compression import ALLOWED_ARCHIVE_TYPES + +def filter_file(regex, repl, *filenames, **kwargs): + """Like sed, but uses python regular expressions. + + Filters every line of file through regex and replaces the file + with a filtered version. Preserves mode of filtered files. + + As with re.sub, ``repl`` can be either a string or a callable. + If it is a callable, it is passed the match object and should + return a suitable replacement string. If it is a string, it + can contain ``\1``, ``\2``, etc. to represent back-substitution + as sed would allow. + + Keyword Options: + string[=False] If True, treat regex as a plain string. + backup[=True] Make a backup files suffixed with ~ + ignore_absent[=False] Ignore any files that don't exist. + """ + string = kwargs.get('string', False) + backup = kwargs.get('backup', True) + ignore_absent = kwargs.get('ignore_absent', False) + + # Allow strings to use \1, \2, etc. for replacement, like sed + if not callable(repl): + unescaped = repl.replace(r'\\', '\\') + def replace_groups_with_groupid(m): + def groupid_to_group(x): + return m.group(int(x.group(1))) + return re.sub(r'\\([1-9])', groupid_to_group, unescaped) + repl = replace_groups_with_groupid + + if string: + regex = re.escape(regex) + + for filename in filenames: + backup = filename + "~" + + if ignore_absent and not os.path.exists(filename): + continue + + shutil.copy(filename, backup) + try: + with closing(open(backup)) as infile: + with closing(open(filename, 'w')) as outfile: + for line in infile: + foo = re.sub(regex, repl, line) + outfile.write(foo) + except: + # clean up the original file on failure. + shutil.move(backup, filename) + raise + + finally: + if not backup: + shutil.rmtree(backup, ignore_errors=True) + + +def change_sed_delimiter(old_delim, new_delim, *filenames): + """Find all sed search/replace commands and change the delimiter. + e.g., if the file contains seds that look like 's///', you can + call change_sed_delimeter('/', '@', file) to change the + delimiter to '@'. + + NOTE that this routine will fail if the delimiter is ' or ". + Handling those is left for future work. + """ + assert(len(old_delim) == 1) + assert(len(new_delim) == 1) + + # TODO: handle these cases one day? + assert(old_delim != '"') + assert(old_delim != "'") + assert(new_delim != '"') + assert(new_delim != "'") + + whole_lines = "^s@([^@]*)@(.*)@[gIp]$" + whole_lines = whole_lines.replace('@', old_delim) + + single_quoted = r"'s@((?:\\'|[^@'])*)@((?:\\'|[^'])*)@[gIp]?'" + single_quoted = single_quoted.replace('@', old_delim) + + double_quoted = r'"s@((?:\\"|[^@"])*)@((?:\\"|[^"])*)@[gIp]?"' + double_quoted = double_quoted.replace('@', old_delim) + + repl = r's@\1@\2@g' + repl = repl.replace('@', new_delim) + + for f in filenames: + filter_file(whole_lines, repl, f) + filter_file(single_quoted, "'%s'" % repl, f) + filter_file(double_quoted, '"%s"' % repl, f) + + +def set_install_permissions(path): + """Set appropriate permissions on the installed file.""" + if os.path.isdir(path): + os.chmod(path, 0755) + else: + os.chmod(path, 0644) + + +def install(src, dest): + """Manually install a file to a particular location.""" + tty.info("Installing %s to %s" % (src, dest)) + shutil.copy(src, dest) + set_install_permissions(dest) + + src_mode = os.stat(src).st_mode + dest_mode = os.stat(dest).st_mode + if src_mode | stat.S_IXUSR: dest_mode |= stat.S_IXUSR + if src_mode | stat.S_IXGRP: dest_mode |= stat.S_IXGRP + if src_mode | stat.S_IXOTH: dest_mode |= stat.S_IXOTH + os.chmod(dest, dest_mode) + + +def is_exe(path): + """True if path is an executable file.""" + return os.path.isfile(path) and os.access(path, os.X_OK) + + +def expand_user(path): + """Find instances of '%u' in a path and replace with the current user's + username.""" + username = getpass.getuser() + if not username and '%u' in path: + tty.die("Couldn't get username to complete path '%s'" % path) + + return path.replace('%u', username) + + +def mkdirp(*paths): + """Creates a directory, as well as parent directories if needed.""" + for path in paths: + if not os.path.exists(path): + os.makedirs(path) + elif not os.path.isdir(path): + raise OSError(errno.EEXIST, "File alredy exists", path) + + +def force_remove(*paths): + """Remove files without printing errors. Like rm -f, does NOT + remove directories.""" + for path in paths: + try: + os.remove(path) + except OSError, e: + pass + +@contextmanager +def working_dir(dirname, **kwargs): + if kwargs.get('create', False): + mkdirp(dirname) + + orig_dir = os.getcwd() + os.chdir(dirname) + yield + os.chdir(orig_dir) + + +def touch(path): + """Creates an empty file at the specified path.""" + with closing(open(path, 'a')) as file: + os.utime(path, None) + + +def touchp(path): + """Like touch, but creates any parent directories needed for the file.""" + mkdirp(os.path.dirname(path)) + touch(path) + + +def join_path(prefix, *args): + path = str(prefix) + for elt in args: + path = os.path.join(path, str(elt)) + return path + + +def ancestor(dir, n=1): + """Get the nth ancestor of a directory.""" + parent = os.path.abspath(dir) + for i in range(n): + parent = os.path.dirname(parent) + return parent + + +def can_access(file_name): + """True if we have read/write access to the file.""" + return os.access(file_name, os.R_OK|os.W_OK) diff --git a/var/spack/packages/blas/package.py b/var/spack/packages/blas/package.py index 7bab63bcd9..0cf495d0c1 100644 --- a/var/spack/packages/blas/package.py +++ b/var/spack/packages/blas/package.py @@ -12,10 +12,6 @@ class Blas(Package): def install(self, spec, prefix): make() - mv = which('mv') # Create a shell wrapper for the mv command. - mkdir = which('mkdir') # Create a shell wrapper for the mkdir command. - pwd = os.getcwd() # Retrieve the current working dir. - mkdir('%s' % prefix.lib) # Create the lib dir inside the install dir. - mv('%s/blas_LINUX.a' % pwd, '%s/libblas.a' % pwd) # Rename the generated lib file to libblas.a - mv('%s/libblas.a' % pwd, '%s/libblas.a' % prefix.lib) # Move the library file to the install dir. + mkdirp('%s' % prefix.lib) # Create the lib dir inside the install dir. + move('./blas_LINUX.a', '%s/libblas.a' % prefix.lib) # Rename the generated lib file to libblas.a diff --git a/var/spack/packages/lapack/package.py b/var/spack/packages/lapack/package.py index f2dab5ecb6..de90acd742 100644 --- a/var/spack/packages/lapack/package.py +++ b/var/spack/packages/lapack/package.py @@ -12,20 +12,15 @@ class Lapack(Package): depends_on('blas') - def install(self, spec, prefix): - mv = which('mv') # Create a shell wrapper for the mv command. - mkdir = which('mkdir') # Create a shell wrapper for the mkdir command. - pwd = os.getcwd() # Retrieve the current working dir. - + def install(self, spec, prefix): # Lapack and BLAS testing fails for some reason, but the library is - # built and ready to go at this point. The testing stuff is going to be - # switched off for now. + # built and ready to go after make() is called. The testing stuff is + # going to be switched off for now. filter_file('blas_testing lapack_testing ', ' ', 'Makefile', string=True) - - mv('%s/make.inc.example' % pwd, '%s/make.inc' % pwd) + move('./make.inc.example', './make.inc') filter_file('../../librefblas.a', '%s/libblas.a' % spec['blas'].prefix.lib, 'make.inc', string=True) # Specify the BLAS lib to use. make() mkdir('%s' % prefix.lib) # Create the lib dir inside the install dir. - mv('%s/liblapack.a' % pwd, '%s/liblapack.a' % prefix.lib) # Move the library file to the install dir. + move('./liblapack.a', '%s/liblapack.a' % prefix.lib) # Move the library file to the install dir. |