From b280034380f82c1badbe320fe6763ef04620c8fe Mon Sep 17 00:00:00 2001
From: Greg Becker <becker33@llnl.gov>
Date: Wed, 13 Nov 2019 16:03:16 -0800
Subject: [PATCH] Allow binary relocation of strings in relative binaries
 (#13724)

Binaries with relative RPATHS currently do not relocate strings
hard-coded in binaries

This PR extends the best-effort relocation of strings hard-coded
in binaries to those whose RPATHs have been relativized.
---
 lib/spack/spack/binary_distribution.py | 17 ++++++++++++++++-
 lib/spack/spack/relocate.py            | 23 +++++++++--------------
 2 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py
index 2dcb75860b..23e5126303 100644
--- a/lib/spack/spack/binary_distribution.py
+++ b/lib/spack/spack/binary_distribution.py
@@ -534,7 +534,22 @@ def relocate_package(workdir, spec, allow_root):
                            newprefix=new_prefix)
     # If the binary files in the package were not edited to use
     # relative RPATHs, then the RPATHs need to be relocated
-    if not rel:
+    if rel:
+        if old_path != new_path:
+            files_to_relocate = list(filter(
+                lambda pathname: not relocate.file_is_relocatable(
+                    pathname, paths_to_relocate=[old_path, old_prefix]),
+                map(lambda filename: os.path.join(workdir, filename),
+                    buildinfo['relocate_binaries'])))
+
+            if len(old_path) < len(new_path) and files_to_relocate:
+                tty.debug('Cannot do a binary string replacement with padding '
+                          'for package because %s is longer than %s.' %
+                          (new_path, old_path))
+            else:
+                for path_name in files_to_relocate:
+                    relocate.replace_prefix_bin(path_name, old_path, new_path)
+    else:
         path_names = set()
         for filename in buildinfo['relocate_binaries']:
             path_name = os.path.join(workdir, filename)
diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py
index 9a54be1c64..472195866e 100644
--- a/lib/spack/spack/relocate.py
+++ b/lib/spack/spack/relocate.py
@@ -637,7 +637,8 @@ def is_relocatable(spec):
     return True
 
 
-def file_is_relocatable(file):
+def file_is_relocatable(
+        file, paths_to_relocate=[spack.store.layout.root, spack.paths.prefix]):
     """Returns True if the file passed as argument is relocatable.
 
     Args:
@@ -684,19 +685,13 @@ def file_is_relocatable(file):
             if idpath is not None:
                 set_of_strings.discard(idpath)
 
-    if any(spack.store.layout.root in x for x in set_of_strings):
-        # One binary has the root folder not in the RPATH,
-        # meaning that this spec is not relocatable
-        msg = 'Found "{0}" in {1} strings'
-        tty.debug(msg.format(spack.store.layout.root, file))
-        return False
-
-    if any(spack.paths.prefix in x for x in set_of_strings):
-        # One binary has the root folder not in the RPATH,
-        # meaning that this spec is not relocatable
-        msg = 'Found "{0}" in {1} strings'
-        tty.debug(msg.format(spack.paths.prefix, file))
-        return False
+    for path_to_relocate in paths_to_relocate:
+        if any(path_to_relocate in x for x in set_of_strings):
+            # One binary has the root folder not in the RPATH,
+            # meaning that this spec is not relocatable
+            msg = 'Found "{0}" in {1} strings'
+            tty.debug(msg.format(path_to_relocate, file))
+            return False
 
     return True
 
-- 
GitLab