Merge branch 'develop' of https://github.com/LLNL/spack into refactoring/stage
Conflicts: lib/spack/spack/package.py
This commit is contained in:
commit
7f4a69319a
24 changed files with 238 additions and 100 deletions
|
@ -19,7 +19,7 @@ written in pure Python, and specs allow package authors to write a
|
||||||
single build script for many different builds of the same package.
|
single build script for many different builds of the same package.
|
||||||
|
|
||||||
See the
|
See the
|
||||||
[Feature Overview](http://llnl.github.io/spack/features.html)
|
[Feature Overview](http://software.llnl.gov/spack/features.html)
|
||||||
for examples and highlights.
|
for examples and highlights.
|
||||||
|
|
||||||
To install spack and install your first package:
|
To install spack and install your first package:
|
||||||
|
@ -31,7 +31,7 @@ To install spack and install your first package:
|
||||||
Documentation
|
Documentation
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
[**Full documentation**](http://llnl.github.io/spack) for Spack is
|
[**Full documentation**](http://software.llnl.gov/spack) for Spack is
|
||||||
the first place to look.
|
the first place to look.
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
|
@ -896,7 +896,7 @@ Or, similarly with modules, you could type:
|
||||||
$ spack load mpich %gcc@4.4.7
|
$ spack load mpich %gcc@4.4.7
|
||||||
|
|
||||||
These commands will add appropriate directories to your ``PATH``,
|
These commands will add appropriate directories to your ``PATH``,
|
||||||
``MANPATH``, and ``LD_LIBRARY_PATH``. When you no longer want to use
|
``MANPATH``, ``CPATH``, and ``LD_LIBRARY_PATH``. When you no longer want to use
|
||||||
a package, you can type unload or unuse similarly:
|
a package, you can type unload or unuse similarly:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
|
@ -22,7 +22,7 @@ go:
|
||||||
$ spack install libelf
|
$ spack install libelf
|
||||||
|
|
||||||
For a richer experience, use Spack's `shell support
|
For a richer experience, use Spack's `shell support
|
||||||
<http://llnl.github.io/spack/basic_usage.html#environment-modules>`_:
|
<http://software.llnl.gov/spack/basic_usage.html#environment-modules>`_:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
|
|
2
lib/spack/env/cc
vendored
2
lib/spack/env/cc
vendored
|
@ -130,7 +130,7 @@ if [ -z "$mode" ]; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Dump the version and exist if we're in testing mode.
|
# Dump the version and exit if we're in testing mode.
|
||||||
if [ "$SPACK_TEST_COMMAND" = "dump-mode" ]; then
|
if [ "$SPACK_TEST_COMMAND" = "dump-mode" ]; then
|
||||||
echo "$mode"
|
echo "$mode"
|
||||||
exit
|
exit
|
||||||
|
|
|
@ -152,15 +152,20 @@ def set_install_permissions(path):
|
||||||
def copy_mode(src, dest):
|
def copy_mode(src, dest):
|
||||||
src_mode = os.stat(src).st_mode
|
src_mode = os.stat(src).st_mode
|
||||||
dest_mode = os.stat(dest).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_IXUSR: dest_mode |= stat.S_IXUSR
|
||||||
if src_mode | stat.S_IXGRP: dest_mode |= stat.S_IXGRP
|
if src_mode & stat.S_IXGRP: dest_mode |= stat.S_IXGRP
|
||||||
if src_mode | stat.S_IXOTH: dest_mode |= stat.S_IXOTH
|
if src_mode & stat.S_IXOTH: dest_mode |= stat.S_IXOTH
|
||||||
os.chmod(dest, dest_mode)
|
os.chmod(dest, dest_mode)
|
||||||
|
|
||||||
|
|
||||||
def install(src, dest):
|
def install(src, dest):
|
||||||
"""Manually install a file to a particular location."""
|
"""Manually install a file to a particular location."""
|
||||||
tty.debug("Installing %s to %s" % (src, dest))
|
tty.debug("Installing %s to %s" % (src, dest))
|
||||||
|
|
||||||
|
# Expand dsst to its eventual full path if it is a directory.
|
||||||
|
if os.path.isdir(dest):
|
||||||
|
dest = join_path(dest, os.path.basename(src))
|
||||||
|
|
||||||
shutil.copy(src, dest)
|
shutil.copy(src, dest)
|
||||||
set_install_permissions(dest)
|
set_install_permissions(dest)
|
||||||
copy_mode(src, dest)
|
copy_mode(src, dest)
|
||||||
|
|
|
@ -58,24 +58,29 @@ def get_checksums(versions, urls, **kwargs):
|
||||||
|
|
||||||
tty.msg("Downloading...")
|
tty.msg("Downloading...")
|
||||||
hashes = []
|
hashes = []
|
||||||
for i, (url, version) in enumerate(zip(urls, versions)):
|
i = 0
|
||||||
|
for url, version in zip(urls, versions):
|
||||||
stage = Stage(url)
|
stage = Stage(url)
|
||||||
try:
|
try:
|
||||||
stage.fetch()
|
stage.fetch()
|
||||||
if i == 0 and first_stage_function:
|
if i == 0 and first_stage_function:
|
||||||
first_stage_function(stage)
|
first_stage_function(stage)
|
||||||
|
|
||||||
hashes.append(
|
hashes.append((version,
|
||||||
spack.util.crypto.checksum(hashlib.md5, stage.archive_file))
|
spack.util.crypto.checksum(hashlib.md5, stage.archive_file)))
|
||||||
except FailedDownloadError, e:
|
except FailedDownloadError, e:
|
||||||
tty.msg("Failed to fetch %s" % url)
|
tty.msg("Failed to fetch %s" % url)
|
||||||
continue
|
continue
|
||||||
|
except Exception, e:
|
||||||
|
tty.msg('Something failed on %s, skipping.\n (%s)' % (url, e))
|
||||||
|
continue
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
if not keep_stage:
|
if not keep_stage:
|
||||||
stage.destroy()
|
stage.destroy()
|
||||||
|
i += 1
|
||||||
|
|
||||||
return zip(versions, hashes)
|
return hashes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||||
# LLNL-CODE-647188
|
# LLNL-CODE-647188
|
||||||
#
|
#
|
||||||
# For details, see https://llnl.github.io/spack
|
# For details, see https://software.llnl.gov/spack
|
||||||
# Please also see the LICENSE file for our notice and the LGPL.
|
# Please also see the LICENSE file for our notice and the LGPL.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -74,51 +74,7 @@ def setup_parser(subparser):
|
||||||
|
|
||||||
def repo_create(args):
|
def repo_create(args):
|
||||||
"""Create a new package repository."""
|
"""Create a new package repository."""
|
||||||
root = canonicalize_path(args.directory)
|
full_path, namespace = create_repo(args.directory, args.namespace)
|
||||||
namespace = args.namespace
|
|
||||||
|
|
||||||
if not args.namespace:
|
|
||||||
namespace = os.path.basename(root)
|
|
||||||
|
|
||||||
if not re.match(r'\w[\.\w-]*', namespace):
|
|
||||||
tty.die("'%s' is not a valid namespace." % namespace)
|
|
||||||
|
|
||||||
existed = False
|
|
||||||
if os.path.exists(root):
|
|
||||||
if os.path.isfile(root):
|
|
||||||
tty.die('File %s already exists and is not a directory' % root)
|
|
||||||
elif os.path.isdir(root):
|
|
||||||
if not os.access(root, os.R_OK | os.W_OK):
|
|
||||||
tty.die('Cannot create new repo in %s: cannot access directory.' % root)
|
|
||||||
if os.listdir(root):
|
|
||||||
tty.die('Cannot create new repo in %s: directory is not empty.' % root)
|
|
||||||
existed = True
|
|
||||||
|
|
||||||
full_path = os.path.realpath(root)
|
|
||||||
parent = os.path.dirname(full_path)
|
|
||||||
if not os.access(parent, os.R_OK | os.W_OK):
|
|
||||||
tty.die("Cannot create repository in %s: can't access parent!" % root)
|
|
||||||
|
|
||||||
try:
|
|
||||||
config_path = os.path.join(root, repo_config_name)
|
|
||||||
packages_path = os.path.join(root, packages_dir_name)
|
|
||||||
|
|
||||||
mkdirp(packages_path)
|
|
||||||
with open(config_path, 'w') as config:
|
|
||||||
config.write("repo:\n")
|
|
||||||
config.write(" namespace: '%s'\n" % namespace)
|
|
||||||
|
|
||||||
except (IOError, OSError) as e:
|
|
||||||
tty.die('Failed to create new repository in %s.' % root,
|
|
||||||
"Caused by %s: %s" % (type(e), e))
|
|
||||||
|
|
||||||
# try to clean up.
|
|
||||||
if existed:
|
|
||||||
shutil.rmtree(config_path, ignore_errors=True)
|
|
||||||
shutil.rmtree(packages_path, ignore_errors=True)
|
|
||||||
else:
|
|
||||||
shutil.rmtree(root, ignore_errors=True)
|
|
||||||
|
|
||||||
tty.msg("Created repo with namespace '%s'." % namespace)
|
tty.msg("Created repo with namespace '%s'." % namespace)
|
||||||
tty.msg("To register it with spack, run this command:",
|
tty.msg("To register it with spack, run this command:",
|
||||||
'spack repo add %s' % full_path)
|
'spack repo add %s' % full_path)
|
||||||
|
|
|
@ -174,7 +174,11 @@ def version(pkg, ver, checksum=None, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def _depends_on(pkg, spec, when=None):
|
def _depends_on(pkg, spec, when=None):
|
||||||
if when is None:
|
# If when is False do nothing
|
||||||
|
if when is False:
|
||||||
|
return
|
||||||
|
# If when is None or True make sure the condition is always satisfied
|
||||||
|
if when is None or when is True:
|
||||||
when = pkg.name
|
when = pkg.name
|
||||||
when_spec = parse_anonymous_spec(when, pkg.name)
|
when_spec = parse_anonymous_spec(when, pkg.name)
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,9 @@ def __init__(self, root, **kwargs):
|
||||||
|
|
||||||
self.spec_file_name = 'spec.yaml'
|
self.spec_file_name = 'spec.yaml'
|
||||||
self.extension_file_name = 'extensions.yaml'
|
self.extension_file_name = 'extensions.yaml'
|
||||||
self.build_log_name = 'build.out' # TODO: use config file.
|
self.build_log_name = 'build.out' # build log.
|
||||||
|
self.build_env_name = 'build.env' # build environment
|
||||||
|
self.packages_dir = 'repos' # archive of package.py files
|
||||||
|
|
||||||
# Cache of already written/read extension maps.
|
# Cache of already written/read extension maps.
|
||||||
self._extension_maps = {}
|
self._extension_maps = {}
|
||||||
|
@ -231,6 +233,16 @@ def build_log_path(self, spec):
|
||||||
self.build_log_name)
|
self.build_log_name)
|
||||||
|
|
||||||
|
|
||||||
|
def build_env_path(self, spec):
|
||||||
|
return join_path(self.path_for_spec(spec), self.metadata_dir,
|
||||||
|
self.build_env_name)
|
||||||
|
|
||||||
|
|
||||||
|
def build_packages_path(self, spec):
|
||||||
|
return join_path(self.path_for_spec(spec), self.metadata_dir,
|
||||||
|
self.packages_dir)
|
||||||
|
|
||||||
|
|
||||||
def create_install_directory(self, spec):
|
def create_install_directory(self, spec):
|
||||||
_check_concrete(spec)
|
_check_concrete(spec)
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
* /bin directories to be appended to PATH
|
* /bin directories to be appended to PATH
|
||||||
* /lib* directories for LD_LIBRARY_PATH
|
* /lib* directories for LD_LIBRARY_PATH
|
||||||
|
* /include directories for CPATH
|
||||||
* /man* and /share/man* directories for MANPATH
|
* /man* and /share/man* directories for MANPATH
|
||||||
* the package prefix for CMAKE_PREFIX_PATH
|
* the package prefix for CMAKE_PREFIX_PATH
|
||||||
|
|
||||||
|
@ -121,6 +122,7 @@ def add_path(path_name, directory):
|
||||||
('LIBRARY_PATH', self.spec.prefix.lib64),
|
('LIBRARY_PATH', self.spec.prefix.lib64),
|
||||||
('LD_LIBRARY_PATH', self.spec.prefix.lib),
|
('LD_LIBRARY_PATH', self.spec.prefix.lib),
|
||||||
('LD_LIBRARY_PATH', self.spec.prefix.lib64),
|
('LD_LIBRARY_PATH', self.spec.prefix.lib64),
|
||||||
|
('CPATH', self.spec.prefix.include),
|
||||||
('PKG_CONFIG_PATH', join_path(self.spec.prefix.lib, 'pkgconfig')),
|
('PKG_CONFIG_PATH', join_path(self.spec.prefix.lib, 'pkgconfig')),
|
||||||
('PKG_CONFIG_PATH', join_path(self.spec.prefix.lib64, 'pkgconfig'))]:
|
('PKG_CONFIG_PATH', join_path(self.spec.prefix.lib64, 'pkgconfig'))]:
|
||||||
|
|
||||||
|
|
|
@ -193,10 +193,11 @@ def install(self, prefix):
|
||||||
platform-specific versions. There's not much we can do to get
|
platform-specific versions. There's not much we can do to get
|
||||||
around this because of the way decorators work.
|
around this because of the way decorators work.
|
||||||
"""
|
"""
|
||||||
class when(object):
|
|
||||||
def __init__(self, spec):
|
def __init__(self, spec):
|
||||||
pkg = get_calling_module_name()
|
pkg = get_calling_module_name()
|
||||||
self.spec = parse_anonymous_spec(spec, pkg)
|
if spec is True:
|
||||||
|
spec = pkg
|
||||||
|
self.spec = parse_anonymous_spec(spec, pkg) if spec is not False else None
|
||||||
|
|
||||||
def __call__(self, method):
|
def __call__(self, method):
|
||||||
# Get the first definition of the method in the calling scope
|
# Get the first definition of the method in the calling scope
|
||||||
|
@ -207,7 +208,9 @@ def __call__(self, method):
|
||||||
if not type(original_method) == SpecMultiMethod:
|
if not type(original_method) == SpecMultiMethod:
|
||||||
original_method = SpecMultiMethod(original_method)
|
original_method = SpecMultiMethod(original_method)
|
||||||
|
|
||||||
original_method.register(self.spec, method)
|
if self.spec is not None:
|
||||||
|
original_method.register(self.spec, method)
|
||||||
|
|
||||||
return original_method
|
return original_method
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
import spack.mirror
|
import spack.mirror
|
||||||
import spack.hooks
|
import spack.hooks
|
||||||
import spack.directives
|
import spack.directives
|
||||||
|
import spack.repository
|
||||||
import spack.build_environment
|
import spack.build_environment
|
||||||
import spack.url
|
import spack.url
|
||||||
import spack.util.web
|
import spack.util.web
|
||||||
|
@ -66,6 +67,7 @@
|
||||||
from spack.stage import Stage, ResourceStage, StageComposite
|
from spack.stage import Stage, ResourceStage, StageComposite
|
||||||
from spack.util.compression import allowed_archive, extension
|
from spack.util.compression import allowed_archive, extension
|
||||||
from spack.util.executable import ProcessError
|
from spack.util.executable import ProcessError
|
||||||
|
from spack.util.environment import dump_environment
|
||||||
|
|
||||||
"""Allowed URL schemes for spack packages."""
|
"""Allowed URL schemes for spack packages."""
|
||||||
_ALLOWED_URL_SCHEMES = ["http", "https", "ftp", "file", "git"]
|
_ALLOWED_URL_SCHEMES = ["http", "https", "ftp", "file", "git"]
|
||||||
|
@ -884,10 +886,14 @@ def real_work():
|
||||||
# Do the real install in the source directory.
|
# Do the real install in the source directory.
|
||||||
self.stage.chdir_to_source()
|
self.stage.chdir_to_source()
|
||||||
|
|
||||||
|
# Save the build environment in a file before building.
|
||||||
|
env_path = join_path(os.getcwd(), 'spack-build.env')
|
||||||
|
|
||||||
# This redirects I/O to a build log (and optionally to the terminal)
|
# This redirects I/O to a build log (and optionally to the terminal)
|
||||||
log_path = join_path(os.getcwd(), 'spack-build.out')
|
log_path = join_path(os.getcwd(), 'spack-build.out')
|
||||||
log_file = open(log_path, 'w')
|
log_file = open(log_path, 'w')
|
||||||
with log_output(log_file, verbose, sys.stdout.isatty(), True):
|
with log_output(log_file, verbose, sys.stdout.isatty(), True):
|
||||||
|
dump_environment(env_path)
|
||||||
self.install(self.spec, self.prefix)
|
self.install(self.spec, self.prefix)
|
||||||
|
|
||||||
# Ensure that something was actually installed.
|
# Ensure that something was actually installed.
|
||||||
|
@ -896,7 +902,12 @@ def real_work():
|
||||||
# Move build log into install directory on success
|
# Move build log into install directory on success
|
||||||
if not fake:
|
if not fake:
|
||||||
log_install_path = spack.install_layout.build_log_path(self.spec)
|
log_install_path = spack.install_layout.build_log_path(self.spec)
|
||||||
|
env_install_path = spack.install_layout.build_env_path(self.spec)
|
||||||
install(log_path, log_install_path)
|
install(log_path, log_install_path)
|
||||||
|
install(env_path, env_install_path)
|
||||||
|
|
||||||
|
packages_dir = spack.install_layout.build_packages_path(self.spec)
|
||||||
|
dump_packages(self.spec, packages_dir)
|
||||||
|
|
||||||
# On successful install, remove the stage.
|
# On successful install, remove the stage.
|
||||||
if not keep_stage:
|
if not keep_stage:
|
||||||
|
@ -1205,6 +1216,52 @@ def validate_package_url(url_string):
|
||||||
tty.die("Invalid file type in URL: '%s'" % url_string)
|
tty.die("Invalid file type in URL: '%s'" % url_string)
|
||||||
|
|
||||||
|
|
||||||
|
def dump_packages(spec, path):
|
||||||
|
"""Dump all package information for a spec and its dependencies.
|
||||||
|
|
||||||
|
This creates a package repository within path for every
|
||||||
|
namespace in the spec DAG, and fills the repos wtih package
|
||||||
|
files and patch files for every node in the DAG.
|
||||||
|
"""
|
||||||
|
mkdirp(path)
|
||||||
|
|
||||||
|
# Copy in package.py files from any dependencies.
|
||||||
|
# Note that we copy them in as they are in the *install* directory
|
||||||
|
# NOT as they are in the repository, because we want a snapshot of
|
||||||
|
# how *this* particular build was done.
|
||||||
|
for node in spec.traverse():
|
||||||
|
if node is not spec:
|
||||||
|
# Locate the dependency package in the install tree and find
|
||||||
|
# its provenance information.
|
||||||
|
source = spack.install_layout.build_packages_path(node)
|
||||||
|
source_repo_root = join_path(source, node.namespace)
|
||||||
|
|
||||||
|
# There's no provenance installed for the source package. Skip it.
|
||||||
|
# User can always get something current from the builtin repo.
|
||||||
|
if not os.path.isdir(source_repo_root):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Create a source repo and get the pkg directory out of it.
|
||||||
|
try:
|
||||||
|
source_repo = spack.repository.Repo(source_repo_root)
|
||||||
|
source_pkg_dir = source_repo.dirname_for_package_name(node.name)
|
||||||
|
except RepoError as e:
|
||||||
|
tty.warn("Warning: Couldn't copy in provenance for %s" % node.name)
|
||||||
|
|
||||||
|
# Create a destination repository
|
||||||
|
dest_repo_root = join_path(path, node.namespace)
|
||||||
|
if not os.path.exists(dest_repo_root):
|
||||||
|
spack.repository.create_repo(dest_repo_root)
|
||||||
|
repo = spack.repository.Repo(dest_repo_root)
|
||||||
|
|
||||||
|
# Get the location of the package in the dest repo.
|
||||||
|
dest_pkg_dir = repo.dirname_for_package_name(node.name)
|
||||||
|
if node is not spec:
|
||||||
|
install_tree(source_pkg_dir, dest_pkg_dir)
|
||||||
|
else:
|
||||||
|
spack.repo.dump_provenance(node, dest_pkg_dir)
|
||||||
|
|
||||||
|
|
||||||
def print_pkg(message):
|
def print_pkg(message):
|
||||||
"""Outputs a message with a package icon."""
|
"""Outputs a message with a package icon."""
|
||||||
from llnl.util.tty.color import cwrite
|
from llnl.util.tty.color import cwrite
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||||
# LLNL-CODE-647188
|
# LLNL-CODE-647188
|
||||||
#
|
#
|
||||||
# For details, see https://llnl.github.io/spack
|
# For details, see https://software.llnl.gov/spack
|
||||||
# Please also see the LICENSE file for our notice and the LGPL.
|
# Please also see the LICENSE file for our notice and the LGPL.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
from external import yaml
|
from external import yaml
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.filesystem import join_path
|
from llnl.util.filesystem import *
|
||||||
|
|
||||||
import spack.error
|
import spack.error
|
||||||
import spack.config
|
import spack.config
|
||||||
|
@ -316,6 +316,16 @@ def get(self, spec, new=False):
|
||||||
return self.repo_for_pkg(spec).get(spec)
|
return self.repo_for_pkg(spec).get(spec)
|
||||||
|
|
||||||
|
|
||||||
|
@_autospec
|
||||||
|
def dump_provenance(self, spec, path):
|
||||||
|
"""Dump provenance information for a spec to a particular path.
|
||||||
|
|
||||||
|
This dumps the package file and any associated patch files.
|
||||||
|
Raises UnknownPackageError if not found.
|
||||||
|
"""
|
||||||
|
return self.repo_for_pkg(spec).dump_provenance(spec, path)
|
||||||
|
|
||||||
|
|
||||||
def dirname_for_package_name(self, pkg_name):
|
def dirname_for_package_name(self, pkg_name):
|
||||||
return self.repo_for_pkg(pkg_name).dirname_for_package_name(pkg_name)
|
return self.repo_for_pkg(pkg_name).dirname_for_package_name(pkg_name)
|
||||||
|
|
||||||
|
@ -552,6 +562,35 @@ def get(self, spec, new=False):
|
||||||
return self._instances[key]
|
return self._instances[key]
|
||||||
|
|
||||||
|
|
||||||
|
@_autospec
|
||||||
|
def dump_provenance(self, spec, path):
|
||||||
|
"""Dump provenance information for a spec to a particular path.
|
||||||
|
|
||||||
|
This dumps the package file and any associated patch files.
|
||||||
|
Raises UnknownPackageError if not found.
|
||||||
|
"""
|
||||||
|
# Some preliminary checks.
|
||||||
|
if spec.virtual:
|
||||||
|
raise UnknownPackageError(spec.name)
|
||||||
|
|
||||||
|
if spec.namespace and spec.namespace != self.namespace:
|
||||||
|
raise UnknownPackageError("Repository %s does not contain package %s."
|
||||||
|
% (self.namespace, spec.fullname))
|
||||||
|
|
||||||
|
# Install any patch files needed by packages.
|
||||||
|
mkdirp(path)
|
||||||
|
for spec, patches in spec.package.patches.items():
|
||||||
|
for patch in patches:
|
||||||
|
if patch.path:
|
||||||
|
if os.path.exists(patch.path):
|
||||||
|
install(patch.path, path)
|
||||||
|
else:
|
||||||
|
tty.warn("Patch file did not exist: %s" % patch.path)
|
||||||
|
|
||||||
|
# Install the package.py file itself.
|
||||||
|
install(self.filename_for_package_name(spec), path)
|
||||||
|
|
||||||
|
|
||||||
def purge(self):
|
def purge(self):
|
||||||
"""Clear entire package instance cache."""
|
"""Clear entire package instance cache."""
|
||||||
self._instances.clear()
|
self._instances.clear()
|
||||||
|
@ -705,6 +744,58 @@ def __contains__(self, pkg_name):
|
||||||
return self.exists(pkg_name)
|
return self.exists(pkg_name)
|
||||||
|
|
||||||
|
|
||||||
|
def create_repo(root, namespace=None):
|
||||||
|
"""Create a new repository in root with the specified namespace.
|
||||||
|
|
||||||
|
If the namespace is not provided, use basename of root.
|
||||||
|
Return the canonicalized path and the namespace of the created repository.
|
||||||
|
"""
|
||||||
|
root = canonicalize_path(root)
|
||||||
|
if not namespace:
|
||||||
|
namespace = os.path.basename(root)
|
||||||
|
|
||||||
|
if not re.match(r'\w[\.\w-]*', namespace):
|
||||||
|
raise InvalidNamespaceError("'%s' is not a valid namespace." % namespace)
|
||||||
|
|
||||||
|
existed = False
|
||||||
|
if os.path.exists(root):
|
||||||
|
if os.path.isfile(root):
|
||||||
|
raise BadRepoError('File %s already exists and is not a directory' % root)
|
||||||
|
elif os.path.isdir(root):
|
||||||
|
if not os.access(root, os.R_OK | os.W_OK):
|
||||||
|
raise BadRepoError('Cannot create new repo in %s: cannot access directory.' % root)
|
||||||
|
if os.listdir(root):
|
||||||
|
raise BadRepoError('Cannot create new repo in %s: directory is not empty.' % root)
|
||||||
|
existed = True
|
||||||
|
|
||||||
|
full_path = os.path.realpath(root)
|
||||||
|
parent = os.path.dirname(full_path)
|
||||||
|
if not os.access(parent, os.R_OK | os.W_OK):
|
||||||
|
raise BadRepoError("Cannot create repository in %s: can't access parent!" % root)
|
||||||
|
|
||||||
|
try:
|
||||||
|
config_path = os.path.join(root, repo_config_name)
|
||||||
|
packages_path = os.path.join(root, packages_dir_name)
|
||||||
|
|
||||||
|
mkdirp(packages_path)
|
||||||
|
with open(config_path, 'w') as config:
|
||||||
|
config.write("repo:\n")
|
||||||
|
config.write(" namespace: '%s'\n" % namespace)
|
||||||
|
|
||||||
|
except (IOError, OSError) as e:
|
||||||
|
raise BadRepoError('Failed to create new repository in %s.' % root,
|
||||||
|
"Caused by %s: %s" % (type(e), e))
|
||||||
|
|
||||||
|
# try to clean up.
|
||||||
|
if existed:
|
||||||
|
shutil.rmtree(config_path, ignore_errors=True)
|
||||||
|
shutil.rmtree(packages_path, ignore_errors=True)
|
||||||
|
else:
|
||||||
|
shutil.rmtree(root, ignore_errors=True)
|
||||||
|
|
||||||
|
return full_path, namespace
|
||||||
|
|
||||||
|
|
||||||
class RepoError(spack.error.SpackError):
|
class RepoError(spack.error.SpackError):
|
||||||
"""Superclass for repository-related errors."""
|
"""Superclass for repository-related errors."""
|
||||||
|
|
||||||
|
@ -713,6 +804,10 @@ class NoRepoConfiguredError(RepoError):
|
||||||
"""Raised when there are no repositories configured."""
|
"""Raised when there are no repositories configured."""
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidNamespaceError(RepoError):
|
||||||
|
"""Raised when an invalid namespace is encountered."""
|
||||||
|
|
||||||
|
|
||||||
class BadRepoError(RepoError):
|
class BadRepoError(RepoError):
|
||||||
"""Raised when repo layout is invalid."""
|
"""Raised when repo layout is invalid."""
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||||
# LLNL-CODE-647188
|
# LLNL-CODE-647188
|
||||||
#
|
#
|
||||||
# For details, see https://llnl.github.io/spack
|
# For details, see https://software.llnl.gov/spack
|
||||||
# Please also see the LICENSE file for our notice and the LGPL.
|
# Please also see the LICENSE file for our notice and the LGPL.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||||
# LLNL-CODE-647188
|
# LLNL-CODE-647188
|
||||||
#
|
#
|
||||||
# For details, see https://llnl.github.io/spack
|
# For details, see https://software.llnl.gov/spack
|
||||||
# Please also see the LICENSE file for our notice and the LGPL.
|
# Please also see the LICENSE file for our notice and the LGPL.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||||
# LLNL-CODE-647188
|
# LLNL-CODE-647188
|
||||||
#
|
#
|
||||||
# For details, see https://scalability-llnl.github.io/spack
|
# For details, see https://scalability-software.llnl.gov/spack
|
||||||
# Please also see the LICENSE file for our notice and the LGPL.
|
# Please also see the LICENSE file for our notice and the LGPL.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -63,3 +63,10 @@ def pop_keys(dictionary, *keys):
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if key in dictionary:
|
if key in dictionary:
|
||||||
dictionary.pop(key)
|
dictionary.pop(key)
|
||||||
|
|
||||||
|
|
||||||
|
def dump_environment(path):
|
||||||
|
"""Dump the current environment out to a file."""
|
||||||
|
with open(path, 'w') as env_file:
|
||||||
|
for key,val in sorted(os.environ.items()):
|
||||||
|
env_file.write("%s=%s\n" % (key, val))
|
||||||
|
|
|
@ -86,12 +86,12 @@ def _spider(args):
|
||||||
|
|
||||||
if not "Content-type" in resp.headers:
|
if not "Content-type" in resp.headers:
|
||||||
tty.debug("ignoring page " + url)
|
tty.debug("ignoring page " + url)
|
||||||
return pages
|
return pages, links
|
||||||
|
|
||||||
if not resp.headers["Content-type"].startswith('text/html'):
|
if not resp.headers["Content-type"].startswith('text/html'):
|
||||||
tty.debug("ignoring page " + url + " with content type " +
|
tty.debug("ignoring page " + url + " with content type " +
|
||||||
resp.headers["Content-type"])
|
resp.headers["Content-type"])
|
||||||
return pages
|
return pages, links
|
||||||
|
|
||||||
# Do the real GET request when we know it's just HTML.
|
# Do the real GET request when we know it's just HTML.
|
||||||
req.get_method = lambda: "GET"
|
req.get_method = lambda: "GET"
|
||||||
|
@ -173,7 +173,7 @@ def spider(root_url, **kwargs):
|
||||||
performance over a sequential fetch.
|
performance over a sequential fetch.
|
||||||
"""
|
"""
|
||||||
max_depth = kwargs.setdefault('depth', 1)
|
max_depth = kwargs.setdefault('depth', 1)
|
||||||
pages, links = _spider((root_url, set(), root_url, None, 1, max_depth, False))
|
pages, links = _spider((root_url, set(), root_url, None, 1, max_depth, False))
|
||||||
return pages, links
|
return pages, links
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ class Cgal(Package):
|
||||||
depends_on('mpfr')
|
depends_on('mpfr')
|
||||||
depends_on('gmp')
|
depends_on('gmp')
|
||||||
depends_on('zlib')
|
depends_on('zlib')
|
||||||
|
depends_on('cmake')
|
||||||
|
|
||||||
# FIXME : Qt5 dependency missing (needs Qt5 and OpenGL)
|
# FIXME : Qt5 dependency missing (needs Qt5 and OpenGL)
|
||||||
# FIXME : Optional third party libraries missing
|
# FIXME : Optional third party libraries missing
|
||||||
|
|
|
@ -7,6 +7,7 @@ class Expat(Package):
|
||||||
|
|
||||||
version('2.1.0', 'dd7dab7a5fea97d2a6a43f511449b7cd')
|
version('2.1.0', 'dd7dab7a5fea97d2a6a43f511449b7cd')
|
||||||
|
|
||||||
|
depends_on('cmake')
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||||
# LLNL-CODE-647188
|
# LLNL-CODE-647188
|
||||||
#
|
#
|
||||||
# For details, see https://llnl.github.io/spack
|
# For details, see https://software.llnl.gov/spack
|
||||||
# Please also see the LICENSE file for our notice and the LGPL.
|
# Please also see the LICENSE file for our notice and the LGPL.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -196,25 +196,6 @@ class Llvm(Package):
|
||||||
when='@%(version)s' % release,
|
when='@%(version)s' % release,
|
||||||
placement=resources[name].get('placement', None))
|
placement=resources[name].get('placement', None))
|
||||||
|
|
||||||
# SVN - current develop
|
|
||||||
version('develop', svn='http://llvm.org/svn/llvm-project/llvm/trunk')
|
|
||||||
resource(name='clang', svn='http://llvm.org/svn/llvm-project/cfe/trunk',
|
|
||||||
destination='tools', when='@develop', placement='clang')
|
|
||||||
resource(name='compiler-rt', svn='http://llvm.org/svn/llvm-project/compiler-rt/trunk',
|
|
||||||
destination='projects', when='@develop', placement='compiler-rt')
|
|
||||||
resource(name='openmp', svn='http://llvm.org/svn/llvm-project/openmp/trunk',
|
|
||||||
destination='projects', when='@develop', placement='openmp')
|
|
||||||
resource(name='libcxx', svn='http://llvm.org/svn/llvm-project/libcxx/trunk',
|
|
||||||
destination='projects', when='@develop', placement='libcxx')
|
|
||||||
resource(name='libcxxabi', svn='http://llvm.org/svn/llvm-project/libcxxabi/trunk',
|
|
||||||
destination='projects', when='@develop', placement='libcxxabi')
|
|
||||||
resource(name='polly', svn='http://llvm.org/svn/llvm-project/polly/trunk',
|
|
||||||
destination='tools', when='@develop', placement='polly')
|
|
||||||
resource(name='lldb', svn='http://llvm.org/svn/llvm-project/lldb/trunk',
|
|
||||||
destination='tools', when='@develop', placement='lldb')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
env['CXXFLAGS'] = self.compiler.cxx11_flag
|
env['CXXFLAGS'] = self.compiler.cxx11_flag
|
||||||
cmake_args = [ arg for arg in std_cmake_args if 'BUILD_TYPE' not in arg ]
|
cmake_args = [ arg for arg in std_cmake_args if 'BUILD_TYPE' not in arg ]
|
||||||
|
|
|
@ -1,19 +1,28 @@
|
||||||
from spack import *
|
from spack import *
|
||||||
|
|
||||||
class Silo(Package):
|
class Silo(Package):
|
||||||
"""Silo is a library for reading and writing a wide variety of scientific data to binary, disk files."""
|
"""Silo is a library for reading and writing a wide variety of scientific
|
||||||
|
data to binary, disk files."""
|
||||||
|
|
||||||
homepage = "http://wci.llnl.gov/simulation/computer-codes/silo"
|
homepage = "http://wci.llnl.gov/simulation/computer-codes/silo"
|
||||||
url = "https://wci.llnl.gov/content/assets/docs/simulation/computer-codes/silo/silo-4.8/silo-4.8.tar.gz"
|
url = "https://wci.llnl.gov/content/assets/docs/simulation/computer-codes/silo/silo-4.8/silo-4.8.tar.gz"
|
||||||
|
|
||||||
#version('4.9', 'a83eda4f06761a86726e918fc55e782a')
|
|
||||||
version('4.8', 'b1cbc0e7ec435eb656dc4b53a23663c9')
|
version('4.8', 'b1cbc0e7ec435eb656dc4b53a23663c9')
|
||||||
|
|
||||||
depends_on("hdf5@:1.8.12")
|
variant('fortran', default=True, description='Enable Fortran support')
|
||||||
|
|
||||||
|
depends_on("hdf5")
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
configure("--prefix=%s" % prefix,
|
config_args = [
|
||||||
"--with-hdf5=%s" %spec['hdf5'].prefix)
|
'--enable-fortran' if '+fortran' in spec else '--disable-fortran',
|
||||||
|
]
|
||||||
|
|
||||||
|
configure(
|
||||||
|
"--prefix=%s" % prefix,
|
||||||
|
"--with-hdf5=%s,%s" % (spec['hdf5'].prefix.include, spec['hdf5'].prefix.lib),
|
||||||
|
"--with-zlib=%s,%s" % (spec['zlib'].prefix.include, spec['zlib'].prefix.lib),
|
||||||
|
*config_args)
|
||||||
|
|
||||||
make()
|
make()
|
||||||
make("install")
|
make("install")
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||||
# LLNL-CODE-647188
|
# LLNL-CODE-647188
|
||||||
#
|
#
|
||||||
# For details, see https://llnl.github.io/spack
|
# For details, see https://software.llnl.gov/spack
|
||||||
# Please also see the LICENSE file for our notice and the LGPL.
|
# Please also see the LICENSE file for our notice and the LGPL.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
|
Loading…
Reference in a new issue