summaryrefslogtreecommitdiff
path: root/lib/spack/spack/relocate.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/spack/relocate.py')
-rw-r--r--lib/spack/spack/relocate.py135
1 files changed, 56 insertions, 79 deletions
diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py
index 6e508c1881..d338242766 100644
--- a/lib/spack/spack/relocate.py
+++ b/lib/spack/spack/relocate.py
@@ -36,12 +36,16 @@ def get_patchelf():
# as we may need patchelf, find out where it is
if platform.system() == 'Darwin':
return None
- patchelf_spec = spack.cmd.parse_specs("patchelf", concretize=True)[0]
- patchelf = spack.repo.get(patchelf_spec)
- if not patchelf.installed:
- patchelf.do_install()
- patchelf_executable = os.path.join(patchelf.prefix.bin, "patchelf")
- return patchelf_executable
+ patchelf = spack.util.executable.which('patchelf')
+ if patchelf is None:
+ patchelf_spec = spack.cmd.parse_specs("patchelf", concretize=True)[0]
+ patchelf = spack.repo.get(patchelf_spec)
+ if not patchelf.installed:
+ patchelf.do_install()
+ patchelf_executable = os.path.join(patchelf.prefix.bin, "patchelf")
+ return patchelf_executable
+ else:
+ return patchelf.path
def get_existing_elf_rpaths(path_name):
@@ -266,31 +270,22 @@ def modify_elf_object(path_name, new_rpaths):
tty.die('relocation not supported for this platform')
-def needs_binary_relocation(filetype, os_id=None):
+def needs_binary_relocation(m_type, m_subtype):
"""
Check whether the given filetype is a binary that may need relocation.
"""
- retval = False
- if "relocatable" in filetype:
- return False
- if "link to" in filetype:
- return False
- 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" % os_id)
- return retval
+ if m_type == 'application':
+ if (m_subtype == 'x-executable' or m_subtype == 'x-sharedlib' or
+ m_subtype == 'x-mach-binary'):
+ return True
+ return False
-def needs_text_relocation(filetype):
+def needs_text_relocation(m_type, m_subtype):
"""
Check whether the given filetype is text that may need relocation.
"""
- if "link to" in filetype:
- return False
- return ("text" in filetype)
+ return (m_type == "text")
def relocate_binary(path_names, old_dir, new_dir, allow_root):
@@ -302,51 +297,44 @@ def relocate_binary(path_names, old_dir, new_dir, allow_root):
if platform.system() == 'Darwin':
for path_name in path_names:
(rpaths, deps, idpath) = macho_get_paths(path_name)
- # new style buildaches with placeholder in binaries
- if (deps[0].startswith(placeholder) or
- rpaths[0].startswith(placeholder) or
- (idpath and idpath.startswith(placeholder))):
- (new_rpaths,
- new_deps,
- new_idpath) = macho_replace_paths(placeholder,
- new_dir,
- rpaths,
- deps,
- idpath)
- # old style buildcaches with original install root in binaries
- else:
- (new_rpaths,
- new_deps,
- new_idpath) = macho_replace_paths(old_dir,
- new_dir,
- rpaths,
- deps,
- idpath)
+ # one pass to replace placeholder
+ (n_rpaths,
+ n_deps,
+ n_idpath) = macho_replace_paths(placeholder,
+ new_dir,
+ rpaths,
+ deps,
+ idpath)
+ # another pass to replace old_dir
+ (new_rpaths,
+ new_deps,
+ new_idpath) = macho_replace_paths(old_dir,
+ new_dir,
+ n_rpaths,
+ n_deps,
+ n_idpath)
modify_macho_object(path_name,
rpaths, deps, idpath,
new_rpaths, new_deps, new_idpath)
if (not allow_root and
old_dir != new_dir and
- strings_contains_installroot(path_name, old_dir)):
+ not file_is_relocatable(path_name)):
raise InstallRootStringException(path_name, old_dir)
elif platform.system() == 'Linux':
for path_name in path_names:
orig_rpaths = get_existing_elf_rpaths(path_name)
if orig_rpaths:
- if orig_rpaths[0].startswith(placeholder):
- # new style buildaches with placeholder in binaries
- new_rpaths = substitute_rpath(orig_rpaths,
- placeholder, new_dir)
- else:
- # old style buildcaches with original install
- # root in binaries
- new_rpaths = substitute_rpath(orig_rpaths,
- old_dir, new_dir)
+ # one pass to replace placeholder
+ n_rpaths = substitute_rpath(orig_rpaths,
+ placeholder, new_dir)
+ # one pass to replace old_dir
+ new_rpaths = substitute_rpath(n_rpaths,
+ old_dir, new_dir)
modify_elf_object(path_name, new_rpaths)
if (not allow_root and
old_dir != new_dir and
- strings_contains_installroot(path_name, old_dir)):
+ not file_is_relocatable(path_name)):
raise InstallRootStringException(path_name, old_dir)
else:
tty.die("Relocation not implemented for %s" % platform.system())
@@ -379,8 +367,8 @@ def make_binary_relative(cur_path_names, orig_path_names, old_dir, allow_root):
rpaths, deps, idpath,
new_rpaths, new_deps, new_idpath)
if (not allow_root and
- strings_contains_installroot(cur_path)):
- raise InstallRootStringException(cur_path)
+ not file_is_relocatable(cur_path, old_dir)):
+ raise InstallRootStringException(cur_path, old_dir)
elif platform.system() == 'Linux':
for cur_path, orig_path in zip(cur_path_names, orig_path_names):
orig_rpaths = get_existing_elf_rpaths(cur_path)
@@ -388,9 +376,9 @@ def make_binary_relative(cur_path_names, orig_path_names, old_dir, allow_root):
new_rpaths = get_relative_rpaths(orig_path, old_dir,
orig_rpaths)
modify_elf_object(cur_path, new_rpaths)
- if (not allow_root and
- strings_contains_installroot(cur_path, old_dir)):
- raise InstallRootStringException(cur_path, old_dir)
+ if (not allow_root and
+ not file_is_relocatable(cur_path, old_dir)):
+ raise InstallRootStringException(cur_path, old_dir)
else:
tty.die("Prelocation not implemented for %s" % platform.system())
@@ -401,29 +389,16 @@ def make_binary_placeholder(cur_path_names, allow_root):
"""
if platform.system() == 'Darwin':
for cur_path in cur_path_names:
- rpaths, deps, idpath = macho_get_paths(cur_path)
- (new_rpaths,
- new_deps,
- new_idpath) = macho_make_paths_placeholder(rpaths, deps, idpath)
- modify_macho_object(cur_path,
- rpaths, deps, idpath,
- new_rpaths, new_deps, new_idpath)
if (not allow_root and
- strings_contains_installroot(cur_path,
- spack.store.layout.root)):
+ not file_is_relocatable(cur_path)):
raise InstallRootStringException(
cur_path, spack.store.layout.root)
elif platform.system() == 'Linux':
for cur_path in cur_path_names:
- orig_rpaths = get_existing_elf_rpaths(cur_path)
- if orig_rpaths:
- new_rpaths = get_placeholder_rpaths(cur_path, orig_rpaths)
- modify_elf_object(cur_path, new_rpaths)
- if (not allow_root and
- strings_contains_installroot(
- cur_path, spack.store.layout.root)):
- raise InstallRootStringException(
- cur_path, spack.store.layout.root)
+ if (not allow_root and
+ not file_is_relocatable(cur_path)):
+ raise InstallRootStringException(
+ cur_path, spack.store.layout.root)
else:
tty.die("Placeholder not implemented for %s" % platform.system())
@@ -498,6 +473,8 @@ def is_relocatable(spec):
raise ValueError('spec is not installed [{0}]'.format(str(spec)))
if spec.external or spec.virtual:
+ tty.warn('external or virtual package %s is not relocatable' %
+ spec.name)
return False
# Explore the installation prefix of the spec
@@ -538,7 +515,7 @@ def file_is_relocatable(file):
raise ValueError('{0} is not an absolute path'.format(file))
strings = Executable('strings')
- patchelf = Executable('patchelf')
+ patchelf = Executable(get_patchelf())
# Remove the RPATHS from the strings in the executable
set_of_strings = set(strings(file, output=str).split())
@@ -600,6 +577,6 @@ def mime_type(file):
Tuple containing the MIME type and subtype
"""
file_cmd = Executable('file')
- output = file_cmd('-b', '--mime-type', file, output=str, error=str)
+ output = file_cmd('-b', '-h', '--mime-type', file, output=str, error=str)
tty.debug('[MIME_TYPE] {0} -> {1}'.format(file, output.strip()))
return tuple(output.strip().split('/'))