summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPatrick Gartung <gartung@fnal.gov>2019-07-01 10:16:23 -0500
committerGitHub <noreply@github.com>2019-07-01 10:16:23 -0500
commit9bf9c0cec3509e3618d968a0694cef22fbafcd2f (patch)
tree3912ca94a7381f4f10d17bab8567d0df7e017283 /lib
parent0f703b7e81f2f9ba36179e6a70172ab5105ae220 (diff)
downloadspack-9bf9c0cec3509e3618d968a0694cef22fbafcd2f.tar.gz
spack-9bf9c0cec3509e3618d968a0694cef22fbafcd2f.tar.bz2
spack-9bf9c0cec3509e3618d968a0694cef22fbafcd2f.tar.xz
spack-9bf9c0cec3509e3618d968a0694cef22fbafcd2f.zip
buildcache: add replace_prefix_bin function to deal with hard coded paths in libraries and executables. (#11882)
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/relocate.py35
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py
index 8277cca068..cbee103699 100644
--- a/lib/spack/spack/relocate.py
+++ b/lib/spack/spack/relocate.py
@@ -289,6 +289,31 @@ def needs_text_relocation(m_type, m_subtype):
return (m_type == "text")
+def replace_prefix_bin(path_name, old_dir, new_dir):
+ """
+ Attempt to replace old install prefix with new install prefix
+ in binary files by replacing with null terminated string
+ that is the same length unless the old path is shorter
+ """
+
+ def replace(match):
+ occurances = match.group().count(old_dir)
+ padding = (len(old_dir) - len(new_dir)) * occurances
+ if padding < 0:
+ return data
+ return match.group().replace(old_dir, new_dir) + b'\0' * padding
+
+ with open(path_name, 'rb+') as f:
+ data = f.read()
+ f.seek(0)
+ original_data_len = len(data)
+ pat = re.compile(re.escape(old_dir) + b'([^\0]*?)\0')
+ data = pat.sub(replace, data)
+ assert(len(data) == original_data_len)
+ f.write(data)
+ f.truncate()
+
+
def relocate_binary(path_names, old_dir, new_dir, allow_root):
"""
Change old_dir to new_dir in RPATHs of elf or mach-o files
@@ -317,10 +342,7 @@ def relocate_binary(path_names, old_dir, new_dir, allow_root):
modify_macho_object(path_name,
rpaths, deps, idpath,
new_rpaths, new_deps, new_idpath)
- if (not allow_root and
- old_dir != new_dir and
- not file_is_relocatable(path_name)):
- raise InstallRootStringException(path_name, old_dir)
+ replace_prefix_bin(path_name, old_dir, new_dir)
elif platform.system() == 'Linux':
for path_name in path_names:
@@ -333,10 +355,7 @@ def relocate_binary(path_names, old_dir, new_dir, allow_root):
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
- not file_is_relocatable(path_name)):
- raise InstallRootStringException(path_name, old_dir)
+ replace_prefix_bin(path_name, old_dir, new_dir)
else:
tty.die("Relocation not implemented for %s" % platform.system())