Merge branch 'features/python-modules' into features/memaxes

Conflicts:
	var/spack/packages/qt/package.py
This commit is contained in:
Todd Gamblin 2015-02-12 10:01:58 -08:00
commit 0c94a6e2b0
16 changed files with 143 additions and 38 deletions

View File

@ -221,3 +221,8 @@ def setup_package(pkg):
set_compiler_environment_variables(pkg) set_compiler_environment_variables(pkg)
set_build_environment_variables(pkg) set_build_environment_variables(pkg)
set_module_variables_for_package(pkg) set_module_variables_for_package(pkg)
# Allow dependencies to set up environment as well.
for dep_spec in pkg.spec.traverse(root=False):
dep_spec.package.setup_dependent_environment(
pkg.module, dep_spec, pkg.spec)

View File

@ -23,6 +23,7 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
from external import argparse from external import argparse
import subprocess
import llnl.util.tty as tty import llnl.util.tty as tty

View File

@ -75,14 +75,15 @@ def extensions(parser, args):
if not extensions: if not extensions:
tty.msg("%s has no extensions." % spec.cshort_spec) tty.msg("%s has no extensions." % spec.cshort_spec)
return return
tty.msg("%s extensions:" % spec.cshort_spec) tty.msg(spec.cshort_spec)
tty.msg("%d extensions:" % len(extensions))
colify(ext.name for ext in extensions) colify(ext.name for ext in extensions)
# List specs of installed extensions. # List specs of installed extensions.
installed = [s.spec for s in spack.db.installed_extensions_for(spec)] installed = [s.spec for s in spack.db.installed_extensions_for(spec)]
print print
if not installed: if not installed:
tty.msg("None activated.") tty.msg("None installed.")
return return
tty.msg("%d installed:" % len(installed)) tty.msg("%d installed:" % len(installed))
spack.cmd.find.display_specs(installed, mode=args.mode) spack.cmd.find.display_specs(installed, mode=args.mode)
@ -93,5 +94,5 @@ def extensions(parser, args):
if not activated: if not activated:
tty.msg("None activated.") tty.msg("None activated.")
return return
tty.msg("%d currently activated:" % len(exts)) tty.msg("%d currently activated:" % len(activated))
spack.cmd.find.display_specs(installed, mode=args.mode) spack.cmd.find.display_specs(activated, mode=args.mode)

View File

@ -109,12 +109,17 @@ def path_for_spec(self, spec):
def remove_path_for_spec(self, spec): def remove_path_for_spec(self, spec):
"""Removes a prefix and any empty parent directories from the root.""" """Removes a prefix and any empty parent directories from the root.
Raised RemoveFailedError if something goes wrong.
"""
path = self.path_for_spec(spec) path = self.path_for_spec(spec)
assert(path.startswith(self.root)) assert(path.startswith(self.root))
if os.path.exists(path): if os.path.exists(path):
shutil.rmtree(path, True) try:
shutil.rmtree(path)
except exceptions.OSError, e:
raise RemoveFailedError(spec, path, e)
path = os.path.dirname(path) path = os.path.dirname(path)
while path != self.root: while path != self.root:
@ -330,6 +335,15 @@ def __init__(self, installed_spec, new_spec):
% installed_spec, new_spec) % installed_spec, new_spec)
class RemoveFailedError(DirectoryLayoutError):
"""Raised when a DirectoryLayout cannot remove an install prefix."""
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)
self.cause = error
class InconsistentInstallDirectoryError(DirectoryLayoutError): class InconsistentInstallDirectoryError(DirectoryLayoutError):
"""Raised when a package seems to be installed to the wrong place.""" """Raised when a package seems to be installed to the wrong place."""
def __init__(self, message): def __init__(self, message):
@ -370,3 +384,5 @@ def __init__(self, spec, extension_spec):
super(NoSuchExtensionError, self).__init__( super(NoSuchExtensionError, self).__init__(
"%s cannot be removed from %s because it's not installed."% ( "%s cannot be removed from %s because it's not installed."% (
extension_spec.short_spec, spec.short_spec)) extension_spec.short_spec, spec.short_spec))

View File

@ -26,15 +26,11 @@
import spack import spack
def post_install(pkg):
if pkg.is_extension:
pkg.do_activate()
def pre_uninstall(pkg): def pre_uninstall(pkg):
# Need to do this b/c uninstall does not automatically do it. # Need to do this b/c uninstall does not automatically do it.
# TODO: store full graph info in stored .spec file. # TODO: store full graph info in stored .spec file.
pkg.spec.normalize() pkg.spec.normalize()
if pkg.is_extension: if pkg.is_extension:
pkg.do_deactivate() if pkg.activated:
pkg.do_deactivate()

View File

@ -829,11 +829,6 @@ def do_install(self, **kwargs):
self.stage.chdir_to_source() self.stage.chdir_to_source()
build_env.setup_package(self) build_env.setup_package(self)
# Allow extendees to further set up the environment.
if self.is_extension:
self.extendee_spec.package.setup_extension_environment(
self.module, self.extendee_spec, self.spec)
if fake_install: if fake_install:
self.do_fake_install() self.do_fake_install()
else: else:
@ -910,8 +905,8 @@ def module(self):
fromlist=[self.__class__.__name__]) fromlist=[self.__class__.__name__])
def setup_extension_environment(self, module, spec, ext_spec): def setup_dependent_environment(self, module, spec, dependent_spec):
"""Called before the install() method of extensions. """Called before the install() method of dependents.
Default implementation does nothing, but this can be Default implementation does nothing, but this can be
overridden by an extendable package to set up the install overridden by an extendable package to set up the install
@ -930,6 +925,8 @@ def setup_extension_environment(self, module, spec, ext_spec):
put a 'python' Execuable object in the module scope for the put a 'python' Execuable object in the module scope for the
extension package to simplify extension installs. extension package to simplify extension installs.
3. A lot of Qt extensions need QTDIR set. This can be used to do that.
""" """
pass pass

View File

@ -0,0 +1,31 @@
from spack import *
class Geos(Package):
"""GEOS (Geometry Engine - Open Source) is a C++ port of the Java
Topology Suite (JTS). As such, it aims to contain the complete
functionality of JTS in C++. This includes all the OpenGIS
Simple Features for SQL spatial predicate functions and spatial
operators, as well as specific JTS enhanced topology functions."""
homepage = "http://trac.osgeo.org/geos/"
url = "http://download.osgeo.org/geos/geos-3.4.2.tar.bz2"
version('3.4.2', 'fc5df2d926eb7e67f988a43a92683bae')
version('3.4.1', '4c930dec44c45c49cd71f3e0931ded7e')
version('3.4.0', 'e41318fc76b5dc764a69d43ac6b18488')
version('3.3.9', '4794c20f07721d5011c93efc6ccb8e4e')
version('3.3.8', '75be476d0831a2d14958fed76ca266de')
version('3.3.7', '95ab996d22672b067d92c7dee2170460')
version('3.3.6', '6fadfb941541875f4976f75fb0bbc800')
version('3.3.5', '2ba61afb7fe2c5ddf642d82d7b16e75b')
version('3.3.4', '1bb9f14d57ef06ffa41cb1d67acb55a1')
version('3.3.3', '8454e653d7ecca475153cc88fd1daa26')
extends('python')
depends_on('swig')
def install(self, spec, prefix):
configure("--prefix=%s" % prefix,
"--enable-python")
make()
make("install")

View File

@ -8,18 +8,13 @@ class PyBasemap(Package):
version('1.0.7', '48c0557ced9e2c6e440b28b3caff2de8') version('1.0.7', '48c0557ced9e2c6e440b28b3caff2de8')
geos_version = {'1.0.7' : '3.3.3'}
extends('python') extends('python')
depends_on('py-setuptools') depends_on('py-setuptools')
depends_on('py-numpy') depends_on('py-numpy')
depends_on('py-matplotlib') depends_on('py-matplotlib')
depends_on('py-pil') depends_on('py-pil')
depends_on("geos")
def install(self, spec, prefix): def install(self, spec, prefix):
with working_dir('geos-%s' % self.geos_version[str(self.version)]): env['GEOS_DIR'] = spec['geos'].prefix
configure("--prefix=" + prefix)
make()
make("install")
os.environ['GEOS_DIR'] = prefix
python('setup.py', 'install', '--prefix=%s' % prefix) python('setup.py', 'install', '--prefix=%s' % prefix)

View File

@ -9,6 +9,7 @@ class PyBiopython(Package):
extends('python') extends('python')
depends_on('py-mx') depends_on('py-mx')
depends_on('py-numpy')
def install(self, spec, prefix): def install(self, spec, prefix):
python('setup.py', 'install', '--prefix=%s' % prefix) python('setup.py', 'install', '--prefix=%s' % prefix)

View File

@ -8,6 +8,7 @@ class PyGnuplot(Package):
version('1.8', 'abd6f571e7aec68ae7db90a5217cd5b1') version('1.8', 'abd6f571e7aec68ae7db90a5217cd5b1')
extends('python') extends('python')
depends_on('py-numpy')
def install(self, spec, prefix): def install(self, spec, prefix):
python('setup.py', 'install', '--prefix=%s' % prefix) python('setup.py', 'install', '--prefix=%s' % prefix)

View File

@ -8,6 +8,7 @@ class PyLibxml2(Package):
version('2.6.21', '229dd2b3d110a77defeeaa73af83f7f3') version('2.6.21', '229dd2b3d110a77defeeaa73af83f7f3')
extends('python') extends('python')
depends_on('libxml2')
def install(self, spec, prefix): def install(self, spec, prefix):
python('setup.py', 'install', '--prefix=%s' % prefix) python('setup.py', 'install', '--prefix=%s' % prefix)

View File

@ -17,9 +17,12 @@ class PyMatplotlib(Package):
depends_on('py-pytz') depends_on('py-pytz')
depends_on('py-nose') depends_on('py-nose')
depends_on('py-numpy') depends_on('py-numpy')
depends_on('qt')
def install(self, spec, prefix): def install(self, spec, prefix):
python('setup.py', 'install', '--prefix=%s' % prefix) python('setup.py', 'install', '--prefix=%s' % prefix)
if str(self.version) == '1.4.2': if str(self.version) == '1.4.2':
# hack to fix configuration file # hack to fix configuration file
config_file = None config_file = None

View File

@ -10,9 +10,32 @@ class PyPyside(Package):
version('1.2.2', 'c45bc400c8a86d6b35f34c29e379e44d') version('1.2.2', 'c45bc400c8a86d6b35f34c29e379e44d')
extends('python') extends('python')
depends_on('py-setuptools')
depends_on('qt@:4')
def patch(self):
"""Undo PySide RPATH handling and add Spack RPATH."""
# Add Spack's standard CMake args to the sub-builds.
# They're called BY setup.py so we have to patch it.
filter_file(
r'OPTION_CMAKE,',
r'OPTION_CMAKE, ' + (
'"-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=FALSE", '
'"-DCMAKE_INSTALL_RPATH=%s",' % ':'.join(self.rpath)),
'setup.py')
# PySide tries to patch ELF files to remove RPATHs
# Disable this and go with the one we set.
filter_file(
r'rpath_cmd\(pyside_path, srcpath\)',
r'#rpath_cmd(pyside_path, srcpath)',
'pyside_postinstall.py')
def install(self, spec, prefix): def install(self, spec, prefix):
qmake_path = '/usr/lib64/qt4/bin/qmake' python('setup.py', 'install',
if not os.path.exists(qmake_path): '--prefix=%s' % prefix,
raise spack.package.InstallError("Failed to find qmake in %s" % qmake_path) '--jobs=%s' % make_jobs)
python('setup.py', 'install', '--prefix=%s' % prefix, '--qmake=%s' % qmake_path)

View File

@ -0,0 +1,21 @@
from spack import *
class PyShiboken(Package):
"""Shiboken generates bindings for C++ libraries using CPython source code."""
homepage = "https://shiboken.readthedocs.org/"
url = "https://pypi.python.org/packages/source/S/Shiboken/Shiboken-1.2.2.tar.gz"
version('1.2.2', '345cfebda221f525842e079a6141e555')
# TODO: make build dependency
# depends_on("cmake")
extends('python')
depends_on("py-setuptools")
depends_on("libxml2")
depends_on("qt@:4.8")
def install(self, spec, prefix):
python('setup.py', 'install',
'--prefix=%s' % prefix,
'--jobs=%s' % make_jobs)

View File

@ -1,9 +1,10 @@
from spack import *
import spack
import os import os
import re import re
from contextlib import closing from contextlib import closing
from spack import *
import spack
class Python(Package): class Python(Package):
"""The Python programming language.""" """The Python programming language."""
@ -46,7 +47,7 @@ def site_packages_dir(self):
return os.path.join(self.python_lib_dir, 'site-packages') return os.path.join(self.python_lib_dir, 'site-packages')
def setup_extension_environment(self, module, spec, ext_spec): def setup_dependent_environment(self, module, spec, ext_spec):
"""Called before python modules' install() methods. """Called before python modules' install() methods.
In most cases, extensions will only need to have one line:: In most cases, extensions will only need to have one line::
@ -60,12 +61,17 @@ def setup_extension_environment(self, module, spec, ext_spec):
module.python_lib_dir = os.path.join(ext_spec.prefix, self.python_lib_dir) module.python_lib_dir = os.path.join(ext_spec.prefix, self.python_lib_dir)
module.site_packages_dir = os.path.join(ext_spec.prefix, self.site_packages_dir) module.site_packages_dir = os.path.join(ext_spec.prefix, self.site_packages_dir)
# Add site packages directory to the PYTHONPATH
os.environ['PYTHONPATH'] = module.site_packages_dir
# Make the site packages directory if it does not exist already. # Make the site packages directory if it does not exist already.
mkdirp(module.site_packages_dir) mkdirp(module.site_packages_dir)
# Set PYTHONPATH to include site-packages dir for the
# extension and any other python extensions it depends on.
python_paths = []
for d in ext_spec.traverse():
if d.package.extends(self.spec):
python_paths.append(os.path.join(d.prefix, self.site_packages_dir))
os.environ['PYTHONPATH'] = ':'.join(python_paths)
# ======================================================================== # ========================================================================
# Handle specifics of activating and deactivating python modules. # Handle specifics of activating and deactivating python modules.

View File

@ -1,3 +1,4 @@
import os
from spack import * from spack import *
import os import os
@ -30,7 +31,7 @@ class Qt(Package):
depends_on("libmng") depends_on("libmng")
depends_on("jpeg") depends_on("jpeg")
# Webkit # Webkit
# depends_on("gperf") # depends_on("gperf")
# depends_on("flex") # depends_on("flex")
# depends_on("bison") # depends_on("bison")
@ -41,6 +42,12 @@ class Qt(Package):
depends_on("mesa") depends_on("mesa")
depends_on("libxcb") depends_on("libxcb")
def setup_dependent_environment(self, module, spec, dep_spec):
"""Dependencies of Qt find it using the QTDIR environment variable."""
os.environ['QTDIR'] = self.prefix
def patch(self): def patch(self):
if self.spec.satisfies('@4'): if self.spec.satisfies('@4'):
qmake_conf = 'mkspecs/common/g++-base.conf' qmake_conf = 'mkspecs/common/g++-base.conf'
@ -56,7 +63,7 @@ def patch(self):
def install(self, spec, prefix): def install(self, spec, prefix):
# Apparently this is the only way to # Apparently this is the only way to
# "truly" get rid of webkit compiles now... # "truly" get rid of webkit compiles now...
os.rename("qtwebkit","no-qtwebkit") os.rename("qtwebkit","no-qtwebkit")
os.rename("qtwebkit-examples","no-qtwebkit-examples") os.rename("qtwebkit-examples","no-qtwebkit-examples")