install() now takes spec AND prefix

This commit is contained in:
Todd Gamblin 2013-12-25 17:19:51 -08:00
parent 0cd5866eea
commit a4cda94524
21 changed files with 122 additions and 62 deletions

View file

@ -9,6 +9,12 @@
from spack.error import SpackError from spack.error import SpackError
def _check_concrete(spec):
"""If the spec is not concrete, raise a ValueError"""
if not spec.concrete:
raise ValueError('Specs passed to a DirectoryLayout must be concrete!')
class DirectoryLayout(object): class DirectoryLayout(object):
"""A directory layout is used to associate unique paths with specs. """A directory layout is used to associate unique paths with specs.
Different installations are going to want differnet layouts for their Different installations are going to want differnet layouts for their
@ -39,7 +45,8 @@ def make_path_for_spec(self, spec):
def path_for_spec(self, spec): def path_for_spec(self, spec):
"""Return an absolute path from the root to a directory for the spec.""" """Return an absolute path from the root to a directory for the spec."""
assert(spec.concrete) _check_concrete(spec)
path = self.relative_path_for_spec(spec) path = self.relative_path_for_spec(spec)
assert(not path.startswith(self.root)) assert(not path.startswith(self.root))
return os.path.join(self.root, path) return os.path.join(self.root, path)
@ -105,7 +112,7 @@ def __init__(self, root, **kwargs):
def relative_path_for_spec(self, spec): def relative_path_for_spec(self, spec):
assert(spec.concrete) _check_concrete(spec)
path = new_path( path = new_path(
spec.architecture, spec.architecture,
@ -134,7 +141,7 @@ def read_spec(self, path):
def make_path_for_spec(self, spec): def make_path_for_spec(self, spec):
assert(spec.concrete) _check_concrete(spec)
path = self.path_for_spec(spec) path = self.path_for_spec(spec)
spec_file_path = new_path(path, self.spec_file) spec_file_path = new_path(path, self.spec_file)
@ -200,5 +207,3 @@ class InstallDirectoryAlreadyExistsError(DirectoryLayoutError):
def __init__(self, path): def __init__(self, path):
super(InstallDirectoryAlreadyExistsError, self).__init__( super(InstallDirectoryAlreadyExistsError, self).__init__(
"Install path %s already exists!") "Install path %s already exists!")

View file

@ -67,7 +67,7 @@ class Cmake(Package):
url = 'http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz' url = 'http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz'
md5 = '097278785da7182ec0aea8769d06860c' md5 = '097278785da7182ec0aea8769d06860c'
def install(self, prefix): def install(self, spec, prefix):
configure('--prefix=%s' % prefix, configure('--prefix=%s' % prefix,
'--parallel=%s' % make_jobs) '--parallel=%s' % make_jobs)
make() make()
@ -407,27 +407,9 @@ def add_commands_to_module(self):
m.rmtree = shutil.rmtree m.rmtree = shutil.rmtree
m.move = shutil.move m.move = shutil.move
# Useful directories within the prefix # Useful directories within the prefix are encapsulated in
# a Prefix object.
m.prefix = self.prefix m.prefix = self.prefix
m.bin = new_path(self.prefix, 'bin')
m.sbin = new_path(self.prefix, 'sbin')
m.etc = new_path(self.prefix, 'etc')
m.include = new_path(self.prefix, 'include')
m.lib = new_path(self.prefix, 'lib')
m.lib64 = new_path(self.prefix, 'lib64')
m.libexec = new_path(self.prefix, 'libexec')
m.share = new_path(self.prefix, 'share')
m.doc = new_path(m.share, 'doc')
m.info = new_path(m.share, 'info')
m.man = new_path(m.share, 'man')
m.man1 = new_path(m.man, 'man1')
m.man2 = new_path(m.man, 'man2')
m.man3 = new_path(m.man, 'man3')
m.man4 = new_path(m.man, 'man4')
m.man5 = new_path(m.man, 'man5')
m.man6 = new_path(m.man, 'man6')
m.man7 = new_path(m.man, 'man7')
m.man8 = new_path(m.man, 'man8')
def preorder_traversal(self, visited=None, **kwargs): def preorder_traversal(self, visited=None, **kwargs):
@ -529,7 +511,7 @@ def installed_dependents(self):
@property @property
def prefix(self): def prefix(self):
"""Get the prefix into which this package should be installed.""" """Get the prefix into which this package should be installed."""
return spack.install_layout.path_for_spec(self.spec) return self.spec.prefix
def url_version(self, version): def url_version(self, version):
@ -620,7 +602,7 @@ def do_install(self):
# case it needs to add extra files) # case it needs to add extra files)
spack.install_layout.make_path_for_spec(self.spec) spack.install_layout.make_path_for_spec(self.spec)
self.install(self.prefix) self.install(self.spec, self.prefix)
if not os.path.isdir(self.prefix): if not os.path.isdir(self.prefix):
tty.die("Install failed for %s. No install dir created." % self.name) tty.die("Install failed for %s. No install dir created." % self.name)
@ -683,7 +665,7 @@ def module(self):
fromlist=[self.__class__.__name__]) fromlist=[self.__class__.__name__])
def install(self, prefix): def install(self, spec, prefix):
"""Package implementations override this with their own build configuration.""" """Package implementations override this with their own build configuration."""
tty.die("Packages must provide an install method!") tty.die("Packages must provide an install method!")

View file

@ -7,7 +7,7 @@ class Callpath(Package):
depends_on("dyninst") depends_on("dyninst")
depends_on("mpich") depends_on("mpich")
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -5,7 +5,7 @@ class Cmake(Package):
url = 'http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz' url = 'http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz'
versions = { '2.8.10.2' : '097278785da7182ec0aea8769d06860c' } versions = { '2.8.10.2' : '097278785da7182ec0aea8769d06860c' }
def install(self, prefix): def install(self, spec, prefix):
configure('--prefix=%s' % prefix, configure('--prefix=%s' % prefix,
'--parallel=%s' % make_jobs) '--parallel=%s' % make_jobs)
make() make()

View file

@ -11,7 +11,7 @@ class Dyninst(Package):
depends_on("libelf") depends_on("libelf")
depends_on("libdwarf") depends_on("libdwarf")
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -23,21 +23,21 @@ def clean(self):
make('clean') make('clean')
def install(self, prefix): def install(self, spec, prefix):
# dwarf build does not set arguments for ar properly # dwarf build does not set arguments for ar properly
make.add_default_arg('ARFLAGS=rcs') make.add_default_arg('ARFLAGS=rcs')
# Dwarf doesn't provide an install, so we have to do it. # Dwarf doesn't provide an install, so we have to do it.
mkdirp(bin, include, lib, man1) mkdirp(prefix.bin, prefix.include, prefix.lib, prefix.man1)
with working_dir('libdwarf'): with working_dir('libdwarf'):
configure("--prefix=%s" % prefix, '--enable-shared') configure("--prefix=%s" % prefix, '--enable-shared')
make() make()
install('libdwarf.a', lib) install('libdwarf.a', prefix.lib)
install('libdwarf.so', lib) install('libdwarf.so', prefix.lib)
install('libdwarf.h', include) install('libdwarf.h', prefix.include)
install('dwarf.h', include) install('dwarf.h', prefix.include)
with working_dir('dwarfdump2'): with working_dir('dwarfdump2'):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
@ -46,6 +46,6 @@ def install(self, prefix):
# cause a race in parallel # cause a race in parallel
make(parallel=False) make(parallel=False)
install('dwarfdump', bin) install('dwarfdump', prefix.bin)
install('dwarfdump.conf', lib) install('dwarfdump.conf', prefix.lib)
install('dwarfdump.1', man1) install('dwarfdump.1', prefix.man1)

View file

@ -6,7 +6,7 @@ class Libelf(Package):
versions = { '0.8.13' : '4136d7b4c04df68b686570afa26988ac' } versions = { '0.8.13' : '4136d7b4c04df68b686570afa26988ac' }
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix, configure("--prefix=%s" % prefix,
"--enable-shared", "--enable-shared",
"--disable-dependency-tracking", "--disable-dependency-tracking",

View file

@ -6,7 +6,7 @@ class Libunwind(Package):
versions = { '1.1' : 'fb4ea2f6fbbe45bf032cd36e586883ce' } versions = { '1.1' : 'fb4ea2f6fbbe45bf032cd36e586883ce' }
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -13,7 +13,7 @@ class Mpich(Package):
provides('mpi@:3', when='@3:') provides('mpi@:3', when='@3:')
provides('mpi@:1', when='@1:') provides('mpi@:1', when='@1:')
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -7,7 +7,7 @@ class Mpileaks(Package):
depends_on("mpich") depends_on("mpich")
depends_on("callpath") depends_on("callpath")
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -82,6 +82,7 @@
from spack.color import * from spack.color import *
from spack.util.lang import * from spack.util.lang import *
from spack.util.string import * from spack.util.string import *
from spack.util.prefix import Prefix
# Convenient names for color formats so that other things can use them # Convenient names for color formats so that other things can use them
@ -439,6 +440,11 @@ def preorder_traversal(self, visited=None, d=0, **kwargs):
yield elt yield elt
@property
def prefix(self):
return Prefix(spack.install_layout.path_for_spec(self))
def _concretize_helper(self, presets=None, visited=None): def _concretize_helper(self, presets=None, visited=None):
"""Recursive helper function for concretize(). """Recursive helper function for concretize().
This concretizes everything bottom-up. As things are This concretizes everything bottom-up. As things are

View file

@ -11,7 +11,7 @@ class Callpath(Package):
depends_on("dyninst") depends_on("dyninst")
depends_on("mpi") depends_on("mpi")
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -12,7 +12,7 @@ class Dyninst(Package):
depends_on("libelf") depends_on("libelf")
depends_on("libdwarf") depends_on("libdwarf")
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -5,7 +5,7 @@ class Fake(Package):
url = "http://www.fake-spack-example.org/downloads/fake-1.0.tar.gz" url = "http://www.fake-spack-example.org/downloads/fake-1.0.tar.gz"
versions = { '1.0' : 'foobarbaz' } versions = { '1.0' : 'foobarbaz' }
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -23,21 +23,21 @@ def clean(self):
make('clean') make('clean')
def install(self, prefix): def install(self, spec, prefix):
# dwarf build does not set arguments for ar properly # dwarf build does not set arguments for ar properly
make.add_default_arg('ARFLAGS=rcs') make.add_default_arg('ARFLAGS=rcs')
# Dwarf doesn't provide an install, so we have to do it. # Dwarf doesn't provide an install, so we have to do it.
mkdirp(bin, include, lib, man1) mkdirp(prefix.bin, prefix.include, prefix.lib, prefix.man1)
with working_dir('libdwarf'): with working_dir('libdwarf'):
configure("--prefix=%s" % prefix, '--enable-shared') configure("--prefix=%s" % prefix, '--enable-shared')
make() make()
install('libdwarf.a', lib) install('libdwarf.a', prefix.lib)
install('libdwarf.so', lib) install('libdwarf.so', prefix.lib)
install('libdwarf.h', include) install('libdwarf.h', prefix.include)
install('dwarf.h', include) install('dwarf.h', prefix.include)
with working_dir('dwarfdump2'): with working_dir('dwarfdump2'):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
@ -46,6 +46,6 @@ def install(self, prefix):
# cause a race in parallel # cause a race in parallel
make(parallel=False) make(parallel=False)
install('dwarfdump', bin) install('dwarfdump', prefix.bin)
install('dwarfdump.conf', lib) install('dwarfdump.conf', prefix.lib)
install('dwarfdump.1', man1) install('dwarfdump.1', prefix.man1)

View file

@ -8,7 +8,7 @@ class Libelf(Package):
'0.8.12' : 'e21f8273d9f5f6d43a59878dc274fec7', '0.8.12' : 'e21f8273d9f5f6d43a59878dc274fec7',
'0.8.10' : '9db4d36c283d9790d8fa7df1f4d7b4d9' } '0.8.10' : '9db4d36c283d9790d8fa7df1f4d7b4d9' }
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix, configure("--prefix=%s" % prefix,
"--enable-shared", "--enable-shared",
"--disable-dependency-tracking", "--disable-dependency-tracking",

View file

@ -15,7 +15,7 @@ class Mpich(Package):
provides('mpi@:3', when='@3:') provides('mpi@:3', when='@3:')
provides('mpi@:1', when='@1:') provides('mpi@:1', when='@1:')
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -17,7 +17,7 @@ class Mpich2(Package):
provides('mpi@:2.1', when='@1.1:') provides('mpi@:2.1', when='@1.1:')
provides('mpi@:2.2', when='@1.2:') provides('mpi@:2.2', when='@1.2:')
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -12,7 +12,7 @@ class Mpileaks(Package):
depends_on("mpi") depends_on("mpi")
depends_on("callpath") depends_on("callpath")
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -11,7 +11,7 @@ class Zmpi(Package):
provides('mpi@:10.0') provides('mpi@:10.0')
depends_on('fake') depends_on('fake')
def install(self, prefix): def install(self, spec, prefix):
configure("--prefix=%s" % prefix) configure("--prefix=%s" % prefix)
make() make()
make("install") make("install")

View file

@ -0,0 +1,67 @@
"""
This file contains utilities to help with installing packages.
"""
from spack.util.filesystem import new_path
class Prefix(object):
"""This class represents an installation prefix, but provides useful
attributes for referring to directories inside the prefix.
For example, you can do something like this::
prefix = Prefix('/usr')
print prefix.lib
print prefix.lib64
print prefix.bin
print prefix.share
print prefix.man4
This program would print:
/usr/lib
/usr/lib64
/usr/bin
/usr/share
/usr/share/man/man4
In addition, Prefix objects can be added to strings, e.g.:
print "foobar " + prefix
This prints 'foobar /usr". All of this is meant to make custom
installs easy.
"""
def __init__(self, prefix):
self.prefix = prefix
self.bin = new_path(self.prefix, 'bin')
self.sbin = new_path(self.prefix, 'sbin')
self.etc = new_path(self.prefix, 'etc')
self.include = new_path(self.prefix, 'include')
self.lib = new_path(self.prefix, 'lib')
self.lib64 = new_path(self.prefix, 'lib64')
self.libexec = new_path(self.prefix, 'libexec')
self.share = new_path(self.prefix, 'share')
self.doc = new_path(self.share, 'doc')
self.info = new_path(self.share, 'info')
self.man = new_path(self.share, 'man')
self.man1 = new_path(self.man, 'man1')
self.man2 = new_path(self.man, 'man2')
self.man3 = new_path(self.man, 'man3')
self.man4 = new_path(self.man, 'man4')
self.man5 = new_path(self.man, 'man5')
self.man6 = new_path(self.man, 'man6')
self.man7 = new_path(self.man, 'man7')
self.man8 = new_path(self.man, 'man8')
def __str__(self):
return self.prefix
def __add__(self, other):
return str(self) + other
def __radd__(self, other):
return other + str(self)