diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py index 81ac908b36..a406101d2c 100644 --- a/lib/spack/spack/binary_distribution.py +++ b/lib/spack/spack/binary_distribution.py @@ -1796,7 +1796,15 @@ def is_backup_file(file): relocate.relocate_text(text_names, prefix_to_prefix_text) # relocate the install prefixes in binary files including dependencies - relocate.relocate_text_bin(files_to_relocate, prefix_to_prefix_bin) + changed_files = relocate.relocate_text_bin(files_to_relocate, prefix_to_prefix_bin) + + # Add ad-hoc signatures to patched macho files when on macOS. + if "macho" in platform.binary_formats and sys.platform == "darwin": + codesign = which("codesign") + if not codesign: + return + for binary in changed_files: + codesign("-fs-", binary) # If we are installing back to the same location # relocate the sbang location if the spack directory changed diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py index 2303bf22a2..52811dd8cc 100644 --- a/lib/spack/spack/relocate.py +++ b/lib/spack/spack/relocate.py @@ -675,7 +675,7 @@ def relocate_text_bin(binaries, prefixes): Raises: spack.relocate_text.BinaryTextReplaceError: when the new path is longer than the old path """ - BinaryFilePrefixReplacer.from_strings_or_bytes(prefixes).apply(binaries) + return BinaryFilePrefixReplacer.from_strings_or_bytes(prefixes).apply(binaries) def is_relocatable(spec): diff --git a/lib/spack/spack/relocate_text.py b/lib/spack/spack/relocate_text.py index 5d91f75474..bfabcc8632 100644 --- a/lib/spack/spack/relocate_text.py +++ b/lib/spack/spack/relocate_text.py @@ -73,24 +73,28 @@ def is_noop(self) -> bool: """Returns true when the prefix to prefix map is mapping everything to the same location (identity) or there are no prefixes to replace.""" - return not bool(self.prefix_to_prefix) + return not self.prefix_to_prefix def apply(self, filenames: list): + """Returns a list of files that were modified""" + changed_files = [] if self.is_noop: - return + return [] for filename in filenames: - self.apply_to_filename(filename) + if self.apply_to_filename(filename): + changed_files.append(filename) + return changed_files def apply_to_filename(self, filename): if self.is_noop: - return + return False with open(filename, "rb+") as f: - self.apply_to_file(f) + return self.apply_to_file(f) def apply_to_file(self, f): if self.is_noop: - return - self._apply_to_file(f) + return False + return self._apply_to_file(f) class TextFilePrefixReplacer(PrefixReplacer): @@ -122,10 +126,11 @@ def _apply_to_file(self, f): data = f.read() new_data = re.sub(self.regex, replacement, data) if id(data) == id(new_data): - return + return False f.seek(0) f.write(new_data) f.truncate() + return True class BinaryFilePrefixReplacer(PrefixReplacer): @@ -194,6 +199,9 @@ def _apply_to_file(self, f): Arguments: f: file opened in rb+ mode + + Returns: + bool: True if file was modified """ assert f.tell() == 0 @@ -201,6 +209,8 @@ def _apply_to_file(self, f): # but it's nasty to deal with matches across boundaries, so let's stick to # something simple. + modified = True + for match in self.regex.finditer(f.read()): # The matching prefix (old) and its replacement (new) old = match.group(1) @@ -243,6 +253,9 @@ def _apply_to_file(self, f): f.seek(match.start()) f.write(replacement) + modified = True + + return modified class BinaryStringReplacementError(spack.error.SpackError):