summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/relocate.py37
1 files changed, 34 insertions, 3 deletions
diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py
index fb4ff18fae..56fc993b5f 100644
--- a/lib/spack/spack/relocate.py
+++ b/lib/spack/spack/relocate.py
@@ -400,8 +400,41 @@ def replace_prefix_text(path_name, old_dir, new_dir):
def replace_prefix_bin(path_name, old_dir, new_dir):
"""
Attempt to replace old install prefix with new install prefix
+ in binary files by prefixing new install prefix with os.sep
+ until the lengths of the prefixes are the same.
+ """
+
+ def replace(match):
+ occurances = match.group().count(old_dir.encode('utf-8'))
+ olen = len(old_dir.encode('utf-8'))
+ nlen = len(new_dir.encode('utf-8'))
+ padding = (olen - nlen) * occurances
+ if padding < 0:
+ return data
+ return match.group().replace(old_dir.encode('utf-8'),
+ new_dir.encode('utf-8')) + b'\0' * padding
+
+ with open(path_name, 'rb+') as f:
+ data = f.read()
+ f.seek(0)
+ original_data_len = len(data)
+ pat = re.compile(old_dir.encode('utf-8') + b'([^\0]*?)\0')
+ if not pat.search(data):
+ return
+ ndata = pat.sub(replace, data)
+ if not len(ndata) == original_data_len:
+ raise BinaryStringReplacementException(
+ path_name, original_data_len, len(ndata))
+ f.write(ndata)
+ f.truncate()
+
+
+def replace_prefix_nullterm(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
+ Used on linux to replace mach-o rpaths
"""
def replace(match):
@@ -413,7 +446,6 @@ def replace_prefix_bin(path_name, old_dir, new_dir):
return data
return match.group().replace(old_dir.encode('utf-8'),
new_dir.encode('utf-8')) + b'\0' * padding
-
with open(path_name, 'rb+') as f:
data = f.read()
f.seek(0)
@@ -466,8 +498,7 @@ def relocate_macho_binaries(path_names, old_dir, new_dir, allow_root):
modify_object_macholib(path_name, placeholder, new_dir)
modify_object_macholib(path_name, old_dir, new_dir)
if len(new_dir) <= len(old_dir):
- replace_prefix_bin(path_name, old_dir,
- new_dir)
+ replace_prefix_nullterm(path_name, old_dir, new_dir)
else:
tty.warn('Cannot do a binary string replacement'
' with padding for %s'