summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/binary_distribution.py49
-rw-r--r--lib/spack/spack/relocate.py18
-rw-r--r--lib/spack/spack/test/packaging.py55
3 files changed, 68 insertions, 54 deletions
diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py
index fb43f252cf..5a2db06424 100644
--- a/lib/spack/spack/binary_distribution.py
+++ b/lib/spack/spack/binary_distribution.py
@@ -28,6 +28,7 @@ import re
import tarfile
import yaml
import shutil
+import platform
import llnl.util.tty as tty
from spack.util.gpg import Gpg
@@ -44,9 +45,6 @@ from spack.util.executable import ProcessError
import spack.relocate as relocate
-_relocation_blacklist = (".spack", "man")
-
-
class NoOverwriteException(Exception):
pass
@@ -98,41 +96,36 @@ def read_buildinfo_file(prefix):
return buildinfo
-def _find_relocations(prefix):
+def write_buildinfo_file(prefix, workdir, rel=False):
+ """
+ Create a cache file containing information
+ required for the relocation
+ """
text_to_relocate = []
binary_to_relocate = []
+ blacklist = (".spack", "man")
+ os_id = platform.system()
# Do this at during tarball creation to save time when tarball unpacked.
# Used by make_package_relative to determine binaries to change.
for root, dirs, files in os.walk(prefix, topdown=True):
- dirs[:] = [d for d in dirs if d not in _relocation_blacklist]
-
+ dirs[:] = [d for d in dirs if d not in blacklist]
for filename in files:
path_name = os.path.join(root, filename)
filetype = relocate.get_filetype(path_name)
- if relocate.needs_binary_relocation(filetype):
+ if relocate.needs_binary_relocation(filetype, os_id):
rel_path_name = os.path.relpath(path_name, prefix)
binary_to_relocate.append(rel_path_name)
elif relocate.needs_text_relocation(filetype):
rel_path_name = os.path.relpath(path_name, prefix)
text_to_relocate.append(rel_path_name)
- return text_to_relocate, binary_to_relocate
-
-
-def write_buildinfo_file(prefix, rel=False):
- """
- Create a cache file containing information
- required for the relocation
- """
- text_to_relocate, binary_to_relocate = _find_relocations(prefix)
-
# Create buildinfo data and write it to disk
buildinfo = {}
buildinfo['relative_rpaths'] = rel
buildinfo['buildpath'] = spack.store.layout.root
buildinfo['relocate_textfiles'] = text_to_relocate
buildinfo['relocate_binaries'] = binary_to_relocate
- filename = buildinfo_file_name(prefix)
+ filename = buildinfo_file_name(workdir)
with open(filename, 'w') as outfile:
outfile.write(yaml.dump(buildinfo, default_flow_style=True))
@@ -256,7 +249,7 @@ def build_tarball(spec, outdir, force=False, rel=False, yes_to_all=False,
install_tree(spec.prefix, workdir, symlinks=True)
# create info for later relocation and create tar
- write_buildinfo_file(workdir, rel=rel)
+ write_buildinfo_file(spec.prefix, workdir, rel=rel)
# optinally make the paths in the binaries relative to each other
# in the spack install tree before creating tarball
@@ -363,28 +356,20 @@ def relocate_package(prefix):
if new_path == old_path and not rel:
return
- text_relocs = buildinfo['relocate_textfiles']
- binary_relocs = buildinfo['relocate_binaries']
-
- # if there are no relocations, search for them instead
- # TODO: revisit this in a 0.11 point release
- if not text_relocs or not binary_relocs:
- text_relocs, binary_relocs = _find_relocations(prefix)
- rel = False
-
tty.msg("Relocating package from",
"%s to %s." % (old_path, new_path))
path_names = set()
- for filename in text_relocs:
+ for filename in buildinfo['relocate_textfiles']:
path_name = os.path.join(prefix, filename)
- path_names.add(path_name)
+ # Don't add backup files generated by filter_file during install step.
+ if not path_name.endswith('~'):
+ path_names.add(path_name)
relocate.relocate_text(path_names, old_path, new_path)
-
# If the binary files in the package were not edited to use
# relative RPATHs, then the RPATHs need to be relocated
if not rel:
path_names = set()
- for filename in binary_relocs:
+ for filename in buildinfo['relocate_binaries']:
path_name = os.path.join(prefix, filename)
path_names.add(path_name)
relocate.relocate_binary(path_names, old_path, new_path)
diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py
index 246ed7510c..1f62c70231 100644
--- a/lib/spack/spack/relocate.py
+++ b/lib/spack/spack/relocate.py
@@ -210,21 +210,21 @@ def modify_elf_object(path_name, orig_rpath, new_rpath):
tty.die('relocation not supported for this platform')
-def needs_binary_relocation(filetype):
+def needs_binary_relocation(filetype, os_id=None):
"""
Check whether the given filetype is a binary that may need relocation.
"""
retval = False
if "relocatable" in filetype:
return False
- if "symbolic link" in filetype:
+ if "link to" in filetype:
return False
- if platform.system() == 'Darwin':
- return ('Mach-O' in filetype)
- elif platform.system() == 'Linux':
- return ('ELF' in filetype)
+ if os_id == 'Darwin':
+ return ("Mach-O" in filetype)
+ elif os_id == 'Linux':
+ return ("ELF" in filetype)
else:
- tty.die("Relocation not implemented for %s" % platform.system())
+ tty.die("Relocation not implemented for %s" % os_id)
return retval
@@ -232,7 +232,7 @@ def needs_text_relocation(filetype):
"""
Check whether the given filetype is text that may need relocation.
"""
- if "link" in filetype:
+ if "link to" in filetype:
return False
return ("text" in filetype)
@@ -289,7 +289,7 @@ def relocate_text(path_names, old_dir, new_dir):
"""
Replace old path with new path in text file path_name
"""
- filter_file("r'%s'" % old_dir, "r'%s'" % new_dir,
+ filter_file('%s' % old_dir, '%s' % new_dir,
*path_names, backup=False)
diff --git a/lib/spack/spack/test/packaging.py b/lib/spack/spack/test/packaging.py
index f9c77c530f..49e5138c89 100644
--- a/lib/spack/spack/test/packaging.py
+++ b/lib/spack/spack/test/packaging.py
@@ -42,7 +42,7 @@ from spack.spec import Spec
from spack.fetch_strategy import URLFetchStrategy, FetchStrategyComposite
from spack.util.executable import ProcessError
from spack.relocate import needs_binary_relocation, needs_text_relocation
-from spack.relocate import get_patchelf
+from spack.relocate import get_patchelf, relocate_text
from spack.relocate import substitute_rpath, get_relative_rpaths
from spack.relocate import macho_replace_paths, macho_make_paths_relative
from spack.relocate import modify_macho_object, macho_get_paths
@@ -217,10 +217,43 @@ echo $PATH"""
stage.destroy()
-def test_relocate():
- assert (needs_binary_relocation('relocatable') is False)
- assert (needs_binary_relocation('link') is False)
- assert (needs_text_relocation('link') is False)
+def test_relocate_text():
+ # Validate the text path replacement
+ old_dir = '/home/spack/opt/spack'
+ filename = 'dummy.txt'
+ with open(filename, "w") as script:
+ script.write(old_dir)
+ script.close()
+
+ filenames = [filename]
+ new_dir = '/opt/rh/devtoolset/'
+ relocate_text(filenames, old_dir, new_dir)
+
+ with open(filename, "r")as script:
+ for line in script:
+ assert(new_dir in line)
+
+
+def test_needs_relocation():
+ binary_type = (
+ 'ELF 64-bit LSB executable, x86-64, version 1 (SYSV),'
+ ' dynamically linked (uses shared libs),'
+ ' for GNU/Linux x.y.z, stripped')
+
+ assert needs_binary_relocation(binary_type, os_id='Linux')
+ assert not needs_binary_relocation('relocatable',
+ os_id='Linux')
+ assert not needs_binary_relocation('symbolic link to `foo\'',
+ os_id='Linux')
+
+ assert needs_text_relocation('ASCII text')
+ assert not needs_text_relocation('symbolic link to `foo.text\'')
+
+ macho_type = 'Mach-O 64-bit executable x86_64'
+ assert needs_binary_relocation(macho_type, os_id='Darwin')
+
+
+def test_macho_paths():
out = macho_make_paths_relative('/Users/Shares/spack/pkgC/lib/libC.dylib',
'/Users/Shared/spack',
@@ -289,6 +322,8 @@ def test_relocate():
'/usr/local/lib/libloco.dylib'],
None)
+
+def test_elf_paths():
out = get_relative_rpaths(
'/usr/bin/test', '/usr',
('/usr/lib', '/usr/lib64', '/opt/local/lib'))
@@ -303,8 +338,8 @@ def test_relocate():
reason="only works with Mach-o objects")
def test_relocate_macho(tmpdir):
with tmpdir.as_cwd():
- get_patchelf()
- assert (needs_binary_relocation('Mach-O'))
+
+ get_patchelf() # this does nothing on Darwin
rpaths, deps, idpath = macho_get_paths('/bin/bash')
nrpaths, ndeps, nid = macho_make_paths_relative('/bin/bash', '/usr',
@@ -341,9 +376,3 @@ def test_relocate_macho(tmpdir):
'libncurses.5.4.dylib',
rpaths, deps, idpath,
nrpaths, ndeps, nid)
-
-
-@pytest.mark.skipif(sys.platform != 'linux2',
- reason="only works with Elf objects")
-def test_relocate_elf():
- assert (needs_binary_relocation('ELF'))