summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2016-05-17 13:21:51 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2016-05-17 13:21:51 -0700
commit138307dd0ccb897fc71847752f7576f1208abb44 (patch)
treeee19df709d451384ae4297365df22bc3d20f3cfe
parent6384264aa72161f644b57a9d3d3d4f40c8e7f945 (diff)
parent97804279406376273726b231faac4c6342a172fe (diff)
downloadspack-138307dd0ccb897fc71847752f7576f1208abb44.tar.gz
spack-138307dd0ccb897fc71847752f7576f1208abb44.tar.bz2
spack-138307dd0ccb897fc71847752f7576f1208abb44.tar.xz
spack-138307dd0ccb897fc71847752f7576f1208abb44.zip
Merge pull request #955 from trws/lua-rework
complete lua rework
-rw-r--r--lib/spack/spack/directives.py51
-rw-r--r--lib/spack/spack/environment.py38
-rw-r--r--lib/spack/spack/modules.py6
-rw-r--r--var/spack/repos/builtin/packages/lua-luaposix/package.py16
-rw-r--r--var/spack/repos/builtin/packages/lua/package.py105
5 files changed, 170 insertions, 46 deletions
diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py
index 74ee7b0add..51b26773e2 100644
--- a/lib/spack/spack/directives.py
+++ b/lib/spack/spack/directives.py
@@ -45,11 +45,8 @@ The available directives are:
* ``resource``
"""
-__all__ = ['depends_on', 'extends', 'provides', 'patch', 'version',
- 'variant', 'resource']
import re
-import inspect
import os.path
import functools
@@ -67,6 +64,9 @@ from spack.spec import Spec, parse_anonymous_spec
from spack.resource import Resource
from spack.fetch_strategy import from_kwargs
+__all__ = ['depends_on', 'extends', 'provides', 'patch', 'version', 'variant',
+ 'resource']
+
#
# This is a list of all directives, built up as they are defined in
# this file.
@@ -122,15 +122,14 @@ class directive(object):
def __init__(self, dicts=None):
if isinstance(dicts, basestring):
- dicts = (dicts,)
+ dicts = (dicts, )
elif type(dicts) not in (list, tuple):
raise TypeError(
- "dicts arg must be list, tuple, or string. Found %s"
- % type(dicts))
+ "dicts arg must be list, tuple, or string. Found %s" %
+ type(dicts))
self.dicts = dicts
-
def ensure_dicts(self, pkg):
"""Ensure that a package has the dicts required by this directive."""
for d in self.dicts:
@@ -142,7 +141,6 @@ class directive(object):
raise spack.error.SpackError(
"Package %s has non-dict %s attribute!" % (pkg, d))
-
def __call__(self, directive_function):
directives[directive_function.__name__] = self
@@ -259,11 +257,12 @@ def variant(pkg, name, default=False, description=""):
"""Define a variant for the package. Packager can specify a default
value (on or off) as well as a text description."""
- default = bool(default)
+ default = bool(default)
description = str(description).strip()
if not re.match(spack.spec.identifier_re, name):
- raise DirectiveError("Invalid variant name in %s: '%s'" % (pkg.name, name))
+ raise DirectiveError("Invalid variant name in %s: '%s'" %
+ (pkg.name, name))
pkg.variants[name] = Variant(default, description)
@@ -271,31 +270,37 @@ def variant(pkg, name, default=False, description=""):
@directive('resources')
def resource(pkg, **kwargs):
"""
- Define an external resource to be fetched and staged when building the package. Based on the keywords present in the
- dictionary the appropriate FetchStrategy will be used for the resource. Resources are fetched and staged in their
- own folder inside spack stage area, and then linked into the stage area of the package that needs them.
+ Define an external resource to be fetched and staged when building the
+ package. Based on the keywords present in the dictionary the appropriate
+ FetchStrategy will be used for the resource. Resources are fetched and
+ staged in their own folder inside spack stage area, and then linked into
+ the stage area of the package that needs them.
List of recognized keywords:
- * 'when' : (optional) represents the condition upon which the resource is needed
- * 'destination' : (optional) path where to link the resource. This path must be relative to the main package stage
- area.
- * 'placement' : (optional) gives the possibility to fine tune how the resource is linked into the main package stage
- area.
+ * 'when' : (optional) represents the condition upon which the resource is
+ needed
+ * 'destination' : (optional) path where to link the resource. This path
+ must be relative to the main package stage area.
+ * 'placement' : (optional) gives the possibility to fine tune how the
+ resource is linked into the main package stage area.
"""
when = kwargs.get('when', pkg.name)
destination = kwargs.get('destination', "")
placement = kwargs.get('placement', None)
# Check if the path is relative
if os.path.isabs(destination):
- message = "The destination keyword of a resource directive can't be an absolute path.\n"
+ message = "The destination keyword of a resource directive can't be"
+ " an absolute path.\n"
message += "\tdestination : '{dest}\n'".format(dest=destination)
raise RuntimeError(message)
# Check if the path falls within the main package stage area
- test_path = 'stage_folder_root/'
- normalized_destination = os.path.normpath(join_path(test_path, destination)) # Normalized absolute path
+ test_path = 'stage_folder_root'
+ normalized_destination = os.path.normpath(join_path(test_path, destination)
+ ) # Normalized absolute path
if test_path not in normalized_destination:
- message = "The destination folder of a resource must fall within the main package stage directory.\n"
+ message = "The destination folder of a resource must fall within the"
+ " main package stage directory.\n"
message += "\tdestination : '{dest}'\n".format(dest=destination)
raise RuntimeError(message)
when_spec = parse_anonymous_spec(when, pkg.name)
@@ -307,6 +312,7 @@ def resource(pkg, **kwargs):
class DirectiveError(spack.error.SpackError):
"""This is raised when something is wrong with a package directive."""
+
def __init__(self, directive, message):
super(DirectiveError, self).__init__(message)
self.directive = directive
@@ -314,6 +320,7 @@ class DirectiveError(spack.error.SpackError):
class CircularReferenceError(DirectiveError):
"""This is raised when something depends on itself."""
+
def __init__(self, directive, package):
super(CircularReferenceError, self).__init__(
directive,
diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py
index 11998ad8d2..af642dcc9b 100644
--- a/lib/spack/spack/environment.py
+++ b/lib/spack/spack/environment.py
@@ -39,7 +39,8 @@ class NameValueModifier(object):
def __init__(self, name, value, **kwargs):
self.name = name
self.value = value
- self.args = {'name': name, 'value': value}
+ self.separator = kwargs.get('separator', ':')
+ self.args = {'name': name, 'value': value, 'delim': self.separator}
self.args.update(kwargs)
@@ -56,34 +57,36 @@ class UnsetEnv(NameModifier):
class SetPath(NameValueModifier):
def execute(self):
- string_path = concatenate_paths(self.value)
+ string_path = concatenate_paths(self.value, separator=self.separator)
os.environ[self.name] = string_path
class AppendPath(NameValueModifier):
def execute(self):
environment_value = os.environ.get(self.name, '')
- directories = environment_value.split(':') if environment_value else []
+ directories = environment_value.split(
+ self.separator) if environment_value else []
directories.append(os.path.normpath(self.value))
- os.environ[self.name] = ':'.join(directories)
+ os.environ[self.name] = self.separator.join(directories)
class PrependPath(NameValueModifier):
def execute(self):
environment_value = os.environ.get(self.name, '')
- directories = environment_value.split(':') if environment_value else []
+ directories = environment_value.split(
+ self.separator) if environment_value else []
directories = [os.path.normpath(self.value)] + directories
- os.environ[self.name] = ':'.join(directories)
+ os.environ[self.name] = self.separator.join(directories)
class RemovePath(NameValueModifier):
def execute(self):
environment_value = os.environ.get(self.name, '')
- directories = environment_value.split(':') if environment_value else []
- directories = [os.path.normpath(x)
- for x in directories
+ directories = environment_value.split(
+ self.separator) if environment_value else []
+ directories = [os.path.normpath(x) for x in directories
if x != os.path.normpath(self.value)]
- os.environ[self.name] = ':'.join(directories)
+ os.environ[self.name] = self.separator.join(directories)
class EnvironmentModifications(object):
@@ -238,17 +241,19 @@ class EnvironmentModifications(object):
x.execute()
-def concatenate_paths(paths):
+def concatenate_paths(paths, separator=':'):
"""
- Concatenates an iterable of paths into a string of column separated paths
+ Concatenates an iterable of paths into a string of paths separated by
+ separator, defaulting to colon
Args:
paths: iterable of paths
+ separator: the separator to use, default ':'
Returns:
string
"""
- return ':'.join(str(item) for item in paths)
+ return separator.join(str(item) for item in paths)
def set_or_unset_not_first(variable, changes, errstream):
@@ -256,16 +261,13 @@ def set_or_unset_not_first(variable, changes, errstream):
Check if we are going to set or unset something after other modifications
have already been requested
"""
- indexes = [ii
- for ii, item in enumerate(changes)
+ indexes = [ii for ii, item in enumerate(changes)
if ii != 0 and type(item) in [SetEnv, UnsetEnv]]
if indexes:
good = '\t \t{context} at {filename}:{lineno}'
nogood = '\t--->\t{context} at {filename}:{lineno}'
message = 'Suspicious requests to set or unset the variable \'{var}\' found' # NOQA: ignore=E501
- errstream(
- message.format(
- var=variable))
+ errstream(message.format(var=variable))
for ii, item in enumerate(changes):
print_format = nogood if ii in indexes else good
errstream(print_format.format(**item.args))
diff --git a/lib/spack/spack/modules.py b/lib/spack/spack/modules.py
index a35e21c3db..d2b819e80a 100644
--- a/lib/spack/spack/modules.py
+++ b/lib/spack/spack/modules.py
@@ -485,9 +485,9 @@ class TclModule(EnvModule):
path = join_path(spack.share_path, "modules")
environment_modifications_formats = {
- PrependPath: 'prepend-path {name} \"{value}\"\n',
- AppendPath: 'append-path {name} \"{value}\"\n',
- RemovePath: 'remove-path {name} \"{value}\"\n',
+ PrependPath: 'prepend-path --delim "{delim}" {name} \"{value}\"\n',
+ AppendPath: 'append-path --delim "{delim}" {name} \"{value}\"\n',
+ RemovePath: 'remove-path --delim "{delim}" {name} \"{value}\"\n',
SetEnv: 'setenv {name} \"{value}\"\n',
UnsetEnv: 'unsetenv {name}\n'
}
diff --git a/var/spack/repos/builtin/packages/lua-luaposix/package.py b/var/spack/repos/builtin/packages/lua-luaposix/package.py
new file mode 100644
index 0000000000..9e96548f08
--- /dev/null
+++ b/var/spack/repos/builtin/packages/lua-luaposix/package.py
@@ -0,0 +1,16 @@
+from spack import *
+import glob
+
+
+class LuaLuaposix(Package):
+ """Lua posix bindings, including ncurses"""
+ homepage = "https://github.com/luaposix/luaposix/"
+ url = "https://github.com/luaposix/luaposix/archive/release-v33.4.0.tar.gz"
+
+ version('33.4.0', 'b36ff049095f28752caeb0b46144516c')
+
+ extends("lua")
+
+ def install(self, spec, prefix):
+ rockspec = glob.glob('luaposix-*.rockspec')
+ luarocks('--tree=' + prefix, 'install', rockspec[0])
diff --git a/var/spack/repos/builtin/packages/lua/package.py b/var/spack/repos/builtin/packages/lua/package.py
index 9a73a22645..e621967586 100644
--- a/var/spack/repos/builtin/packages/lua/package.py
+++ b/var/spack/repos/builtin/packages/lua/package.py
@@ -25,10 +25,11 @@
from spack import *
import os
+
class Lua(Package):
""" The Lua programming language interpreter and library """
homepage = "http://www.lua.org"
- url = "http://www.lua.org/ftp/lua-5.1.5.tar.gz"
+ url = "http://www.lua.org/ftp/lua-5.1.5.tar.gz"
version('5.3.2', '33278c2ab5ee3c1a875be8d55c1ca2a1')
version('5.3.1', '797adacada8d85761c079390ff1d9961')
@@ -42,17 +43,115 @@ class Lua(Package):
version('5.1.4', 'd0870f2de55d59c1c8419f36e8fac150')
version('5.1.3', 'a70a8dfaa150e047866dc01a46272599')
+ extendable = True
+
depends_on('ncurses')
depends_on('readline')
+ resource(
+ name="luarocks",
+ url="https://keplerproject.github.io/luarocks/releases/"
+ "luarocks-2.3.0.tar.gz",
+ md5="a38126684cf42b7d0e7a3c7cf485defb",
+ destination="luarocks",
+ placement='luarocks')
+
def install(self, spec, prefix):
if spec.satisfies("=darwin-i686") or spec.satisfies("=darwin-x86_64"):
target = 'macosx'
else:
target = 'linux'
make('INSTALL_TOP=%s' % prefix,
- 'MYLDFLAGS=-L%s -lncurses' % spec['ncurses'].prefix.lib,
+ 'MYLDFLAGS=-L%s -L%s ' % (
+ spec['readline'].prefix.lib,
+ spec['ncurses'].prefix.lib),
+ 'MYLIBS=-lncurses',
target)
make('INSTALL_TOP=%s' % prefix,
- 'MYLDFLAGS=-L%s -lncurses' % spec['ncurses'].prefix.lib,
+ 'MYLDFLAGS=-L%s -L%s ' % (
+ spec['readline'].prefix.lib,
+ spec['ncurses'].prefix.lib),
+ 'MYLIBS=-lncurses',
'install')
+
+ with working_dir(os.path.join('luarocks', 'luarocks')):
+ configure('--prefix=' + prefix, '--with-lua=' + prefix)
+ make('build')
+ make('install')
+
+ def append_paths(self, paths, cpaths, path):
+ paths.append(os.path.join(path, '?.lua'))
+ paths.append(os.path.join(path, '?', 'init.lua'))
+ cpaths.append(os.path.join(path, '?.so'))
+
+ def setup_dependent_environment(self, spack_env, run_env, extension_spec):
+ lua_paths = []
+ for d in extension_spec.traverse():
+ if d.package.extends(self.spec):
+ lua_paths.append(os.path.join(d.prefix, self.lua_lib_dir))
+ lua_paths.append(os.path.join(d.prefix, self.lua_share_dir))
+
+ lua_patterns = []
+ lua_cpatterns = []
+ for p in lua_paths:
+ if os.path.isdir(p):
+ self.append_paths(lua_patterns, lua_cpatterns, p)
+
+ # Always add this package's paths
+ for p in (os.path.join(self.spec.prefix, self.lua_lib_dir),
+ os.path.join(self.spec.prefix, self.lua_share_dir)):
+ self.append_paths(lua_patterns, lua_cpatterns, p)
+
+ spack_env.set('LUA_PATH', ';'.join(lua_patterns), separator=';')
+ spack_env.set('LUA_CPATH', ';'.join(lua_cpatterns), separator=';')
+
+ # For run time environment set only the path for extension_spec and
+ # prepend it to LUAPATH
+ if extension_spec.package.extends(self.spec):
+ run_env.prepend_path('LUA_PATH', ';'.join(lua_patterns),
+ separator=';')
+ run_env.prepend_path('LUA_CPATH', ';'.join(lua_cpatterns),
+ separator=';')
+
+ def setup_environment(self, spack_env, run_env):
+ run_env.prepend_path(
+ 'LUA_PATH',
+ os.path.join(self.spec.prefix, self.lua_share_dir, '?.lua'),
+ separator=';')
+ run_env.prepend_path(
+ 'LUA_PATH', os.path.join(self.spec.prefix, self.lua_share_dir, '?',
+ 'init.lua'),
+ separator=';')
+ run_env.prepend_path(
+ 'LUA_PATH',
+ os.path.join(self.spec.prefix, self.lua_lib_dir, '?.lua'),
+ separator=';')
+ run_env.prepend_path(
+ 'LUA_PATH',
+ os.path.join(self.spec.prefix, self.lua_lib_dir, '?', 'init.lua'),
+ separator=';')
+ run_env.prepend_path(
+ 'LUA_CPATH',
+ os.path.join(self.spec.prefix, self.lua_lib_dir, '?.so'),
+ separator=';')
+
+ @property
+ def lua_lib_dir(self):
+ return os.path.join('lib', 'lua', '%d.%d' % self.version[:2])
+
+ @property
+ def lua_share_dir(self):
+ return os.path.join('share', 'lua', '%d.%d' % self.version[:2])
+
+ def setup_dependent_package(self, module, ext_spec):
+ """
+ Called before lua modules's install() methods.
+
+ In most cases, extensions will only need to have two lines::
+
+ luarocks('--tree=' + prefix, 'install', rock_spec_path)
+ """
+ # Lua extension builds can have lua and luarocks executable functions
+ module.lua = Executable(join_path(self.spec.prefix.bin, 'lua'))
+ module.luarocks = Executable(join_path(self.spec.prefix.bin,
+ 'luarocks'))