From a4cda9452449b7ef5c78d838f1315d69f0bdd1c7 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Wed, 25 Dec 2013 17:19:51 -0800 Subject: install() now takes spec AND prefix --- lib/spack/spack/directory_layout.py | 15 ++++-- lib/spack/spack/package.py | 30 +++--------- lib/spack/spack/packages/callpath.py | 2 +- lib/spack/spack/packages/cmake.py | 2 +- lib/spack/spack/packages/dyninst.py | 2 +- lib/spack/spack/packages/libdwarf.py | 18 +++---- lib/spack/spack/packages/libelf.py | 2 +- lib/spack/spack/packages/libunwind.py | 2 +- lib/spack/spack/packages/mpich.py | 2 +- lib/spack/spack/packages/mpileaks.py | 2 +- lib/spack/spack/spec.py | 6 +++ lib/spack/spack/test/mock_packages/callpath.py | 2 +- lib/spack/spack/test/mock_packages/dyninst.py | 2 +- lib/spack/spack/test/mock_packages/fake.py | 2 +- lib/spack/spack/test/mock_packages/libdwarf.py | 18 +++---- lib/spack/spack/test/mock_packages/libelf.py | 2 +- lib/spack/spack/test/mock_packages/mpich.py | 2 +- lib/spack/spack/test/mock_packages/mpich2.py | 2 +- lib/spack/spack/test/mock_packages/mpileaks.py | 2 +- lib/spack/spack/test/mock_packages/zmpi.py | 2 +- lib/spack/spack/util/prefix.py | 67 ++++++++++++++++++++++++++ 21 files changed, 122 insertions(+), 62 deletions(-) create mode 100644 lib/spack/spack/util/prefix.py (limited to 'lib') diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py index aed42f4a2c..7f581dfe29 100644 --- a/lib/spack/spack/directory_layout.py +++ b/lib/spack/spack/directory_layout.py @@ -9,6 +9,12 @@ from spack.util.filesystem import * 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): """A directory layout is used to associate unique paths with specs. Different installations are going to want differnet layouts for their @@ -39,7 +45,8 @@ class DirectoryLayout(object): def path_for_spec(self, 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) assert(not path.startswith(self.root)) return os.path.join(self.root, path) @@ -105,7 +112,7 @@ class SpecHashDirectoryLayout(DirectoryLayout): def relative_path_for_spec(self, spec): - assert(spec.concrete) + _check_concrete(spec) path = new_path( spec.architecture, @@ -134,7 +141,7 @@ class SpecHashDirectoryLayout(DirectoryLayout): def make_path_for_spec(self, spec): - assert(spec.concrete) + _check_concrete(spec) path = self.path_for_spec(spec) spec_file_path = new_path(path, self.spec_file) @@ -200,5 +207,3 @@ class InstallDirectoryAlreadyExistsError(DirectoryLayoutError): def __init__(self, path): super(InstallDirectoryAlreadyExistsError, self).__init__( "Install path %s already exists!") - - diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index cb779c4047..acbc7fc927 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -67,7 +67,7 @@ class Package(object): url = 'http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz' md5 = '097278785da7182ec0aea8769d06860c' - def install(self, prefix): + def install(self, spec, prefix): configure('--prefix=%s' % prefix, '--parallel=%s' % make_jobs) make() @@ -407,27 +407,9 @@ class Package(object): m.rmtree = shutil.rmtree 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.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): @@ -529,7 +511,7 @@ class Package(object): @property def prefix(self): """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): @@ -620,7 +602,7 @@ class Package(object): # case it needs to add extra files) 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): tty.die("Install failed for %s. No install dir created." % self.name) @@ -683,7 +665,7 @@ class Package(object): fromlist=[self.__class__.__name__]) - def install(self, prefix): + def install(self, spec, prefix): """Package implementations override this with their own build configuration.""" tty.die("Packages must provide an install method!") diff --git a/lib/spack/spack/packages/callpath.py b/lib/spack/spack/packages/callpath.py index e5102a5fad..267f4a4e49 100644 --- a/lib/spack/spack/packages/callpath.py +++ b/lib/spack/spack/packages/callpath.py @@ -7,7 +7,7 @@ class Callpath(Package): depends_on("dyninst") depends_on("mpich") - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/packages/cmake.py b/lib/spack/spack/packages/cmake.py index d73cdd2c88..3ee294b134 100644 --- a/lib/spack/spack/packages/cmake.py +++ b/lib/spack/spack/packages/cmake.py @@ -5,7 +5,7 @@ class Cmake(Package): url = 'http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz' versions = { '2.8.10.2' : '097278785da7182ec0aea8769d06860c' } - def install(self, prefix): + def install(self, spec, prefix): configure('--prefix=%s' % prefix, '--parallel=%s' % make_jobs) make() diff --git a/lib/spack/spack/packages/dyninst.py b/lib/spack/spack/packages/dyninst.py index 7648a389ee..187cc2bb5a 100644 --- a/lib/spack/spack/packages/dyninst.py +++ b/lib/spack/spack/packages/dyninst.py @@ -11,7 +11,7 @@ class Dyninst(Package): depends_on("libelf") depends_on("libdwarf") - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/packages/libdwarf.py b/lib/spack/spack/packages/libdwarf.py index 928a007193..3102c3d4dd 100644 --- a/lib/spack/spack/packages/libdwarf.py +++ b/lib/spack/spack/packages/libdwarf.py @@ -23,21 +23,21 @@ class Libdwarf(Package): make('clean') - def install(self, prefix): + def install(self, spec, prefix): # dwarf build does not set arguments for ar properly make.add_default_arg('ARFLAGS=rcs') # 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'): configure("--prefix=%s" % prefix, '--enable-shared') make() - install('libdwarf.a', lib) - install('libdwarf.so', lib) - install('libdwarf.h', include) - install('dwarf.h', include) + install('libdwarf.a', prefix.lib) + install('libdwarf.so', prefix.lib) + install('libdwarf.h', prefix.include) + install('dwarf.h', prefix.include) with working_dir('dwarfdump2'): configure("--prefix=%s" % prefix) @@ -46,6 +46,6 @@ class Libdwarf(Package): # cause a race in parallel make(parallel=False) - install('dwarfdump', bin) - install('dwarfdump.conf', lib) - install('dwarfdump.1', man1) + install('dwarfdump', prefix.bin) + install('dwarfdump.conf', prefix.lib) + install('dwarfdump.1', prefix.man1) diff --git a/lib/spack/spack/packages/libelf.py b/lib/spack/spack/packages/libelf.py index 621444706e..98e8736693 100644 --- a/lib/spack/spack/packages/libelf.py +++ b/lib/spack/spack/packages/libelf.py @@ -6,7 +6,7 @@ class Libelf(Package): versions = { '0.8.13' : '4136d7b4c04df68b686570afa26988ac' } - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix, "--enable-shared", "--disable-dependency-tracking", diff --git a/lib/spack/spack/packages/libunwind.py b/lib/spack/spack/packages/libunwind.py index f53985709e..0366ebefba 100644 --- a/lib/spack/spack/packages/libunwind.py +++ b/lib/spack/spack/packages/libunwind.py @@ -6,7 +6,7 @@ class Libunwind(Package): versions = { '1.1' : 'fb4ea2f6fbbe45bf032cd36e586883ce' } - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/packages/mpich.py b/lib/spack/spack/packages/mpich.py index 8cd201f965..a21db55fe8 100644 --- a/lib/spack/spack/packages/mpich.py +++ b/lib/spack/spack/packages/mpich.py @@ -13,7 +13,7 @@ class Mpich(Package): provides('mpi@:3', when='@3:') provides('mpi@:1', when='@1:') - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/packages/mpileaks.py b/lib/spack/spack/packages/mpileaks.py index ffeb38ea45..41b7df0587 100644 --- a/lib/spack/spack/packages/mpileaks.py +++ b/lib/spack/spack/packages/mpileaks.py @@ -7,7 +7,7 @@ class Mpileaks(Package): depends_on("mpich") depends_on("callpath") - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index c27203f05e..3aba17142b 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -82,6 +82,7 @@ from spack.version import * from spack.color import * from spack.util.lang import * from spack.util.string import * +from spack.util.prefix import Prefix # Convenient names for color formats so that other things can use them @@ -439,6 +440,11 @@ class Spec(object): yield elt + @property + def prefix(self): + return Prefix(spack.install_layout.path_for_spec(self)) + + def _concretize_helper(self, presets=None, visited=None): """Recursive helper function for concretize(). This concretizes everything bottom-up. As things are diff --git a/lib/spack/spack/test/mock_packages/callpath.py b/lib/spack/spack/test/mock_packages/callpath.py index e9ad344eaa..8d8949942f 100644 --- a/lib/spack/spack/test/mock_packages/callpath.py +++ b/lib/spack/spack/test/mock_packages/callpath.py @@ -11,7 +11,7 @@ class Callpath(Package): depends_on("dyninst") depends_on("mpi") - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/test/mock_packages/dyninst.py b/lib/spack/spack/test/mock_packages/dyninst.py index 6940c7788d..c4c779f54c 100644 --- a/lib/spack/spack/test/mock_packages/dyninst.py +++ b/lib/spack/spack/test/mock_packages/dyninst.py @@ -12,7 +12,7 @@ class Dyninst(Package): depends_on("libelf") depends_on("libdwarf") - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/test/mock_packages/fake.py b/lib/spack/spack/test/mock_packages/fake.py index 68077f5f82..c1356180e9 100644 --- a/lib/spack/spack/test/mock_packages/fake.py +++ b/lib/spack/spack/test/mock_packages/fake.py @@ -5,7 +5,7 @@ class Fake(Package): url = "http://www.fake-spack-example.org/downloads/fake-1.0.tar.gz" versions = { '1.0' : 'foobarbaz' } - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/test/mock_packages/libdwarf.py b/lib/spack/spack/test/mock_packages/libdwarf.py index ccfff56286..1bb9fbc889 100644 --- a/lib/spack/spack/test/mock_packages/libdwarf.py +++ b/lib/spack/spack/test/mock_packages/libdwarf.py @@ -23,21 +23,21 @@ class Libdwarf(Package): make('clean') - def install(self, prefix): + def install(self, spec, prefix): # dwarf build does not set arguments for ar properly make.add_default_arg('ARFLAGS=rcs') # 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'): configure("--prefix=%s" % prefix, '--enable-shared') make() - install('libdwarf.a', lib) - install('libdwarf.so', lib) - install('libdwarf.h', include) - install('dwarf.h', include) + install('libdwarf.a', prefix.lib) + install('libdwarf.so', prefix.lib) + install('libdwarf.h', prefix.include) + install('dwarf.h', prefix.include) with working_dir('dwarfdump2'): configure("--prefix=%s" % prefix) @@ -46,6 +46,6 @@ class Libdwarf(Package): # cause a race in parallel make(parallel=False) - install('dwarfdump', bin) - install('dwarfdump.conf', lib) - install('dwarfdump.1', man1) + install('dwarfdump', prefix.bin) + install('dwarfdump.conf', prefix.lib) + install('dwarfdump.1', prefix.man1) diff --git a/lib/spack/spack/test/mock_packages/libelf.py b/lib/spack/spack/test/mock_packages/libelf.py index 75948b26fb..4d6b62b96b 100644 --- a/lib/spack/spack/test/mock_packages/libelf.py +++ b/lib/spack/spack/test/mock_packages/libelf.py @@ -8,7 +8,7 @@ class Libelf(Package): '0.8.12' : 'e21f8273d9f5f6d43a59878dc274fec7', '0.8.10' : '9db4d36c283d9790d8fa7df1f4d7b4d9' } - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix, "--enable-shared", "--disable-dependency-tracking", diff --git a/lib/spack/spack/test/mock_packages/mpich.py b/lib/spack/spack/test/mock_packages/mpich.py index c2a479c07a..351d224dc0 100644 --- a/lib/spack/spack/test/mock_packages/mpich.py +++ b/lib/spack/spack/test/mock_packages/mpich.py @@ -15,7 +15,7 @@ class Mpich(Package): provides('mpi@:3', when='@3:') provides('mpi@:1', when='@1:') - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/test/mock_packages/mpich2.py b/lib/spack/spack/test/mock_packages/mpich2.py index ecf99925cc..382cac977a 100644 --- a/lib/spack/spack/test/mock_packages/mpich2.py +++ b/lib/spack/spack/test/mock_packages/mpich2.py @@ -17,7 +17,7 @@ class Mpich2(Package): provides('mpi@:2.1', when='@1.1:') provides('mpi@:2.2', when='@1.2:') - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/test/mock_packages/mpileaks.py b/lib/spack/spack/test/mock_packages/mpileaks.py index 6f9b143e9d..da71ff65bb 100644 --- a/lib/spack/spack/test/mock_packages/mpileaks.py +++ b/lib/spack/spack/test/mock_packages/mpileaks.py @@ -12,7 +12,7 @@ class Mpileaks(Package): depends_on("mpi") depends_on("callpath") - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/test/mock_packages/zmpi.py b/lib/spack/spack/test/mock_packages/zmpi.py index 93b6193eec..ec7e6fcdab 100644 --- a/lib/spack/spack/test/mock_packages/zmpi.py +++ b/lib/spack/spack/test/mock_packages/zmpi.py @@ -11,7 +11,7 @@ class Zmpi(Package): provides('mpi@:10.0') depends_on('fake') - def install(self, prefix): + def install(self, spec, prefix): configure("--prefix=%s" % prefix) make() make("install") diff --git a/lib/spack/spack/util/prefix.py b/lib/spack/spack/util/prefix.py new file mode 100644 index 0000000000..f0ab790a17 --- /dev/null +++ b/lib/spack/spack/util/prefix.py @@ -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) -- cgit v1.2.3-70-g09d2