diff options
author | Patrick Gartung <gartung@fnal.gov> | 2019-07-01 10:16:23 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-01 10:16:23 -0500 |
commit | 9bf9c0cec3509e3618d968a0694cef22fbafcd2f (patch) | |
tree | 3912ca94a7381f4f10d17bab8567d0df7e017283 /lib | |
parent | 0f703b7e81f2f9ba36179e6a70172ab5105ae220 (diff) | |
download | spack-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.py | 35 |
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()) |