keg_relocate.rb: add new methods

This commit is contained in:
danielnachun 2021-12-06 01:26:02 -08:00
parent b7a69ca5a5
commit edf8327497
No known key found for this signature in database
GPG Key ID: 7343CCAD07E2D0FB

View File

@ -8,6 +8,7 @@ class Keg
LIBRARY_PLACEHOLDER = "@@HOMEBREW_LIBRARY@@"
PERL_PLACEHOLDER = "@@HOMEBREW_PERL@@"
JAVA_PLACEHOLDER = "@@HOMEBREW_JAVA@@"
BINARY_NULL_CHARACTER = "\x00"
class Relocation
extend T::Sig
@ -163,6 +164,49 @@ class Keg
changed_files
end
def relocate_build_prefix(keg, old_prefix, new_prefix)
# Find binaries which match prefix strings.
string_matches = Set.new
keg.each_unique_file_matching(old_prefix) do |file|
string_matches << file
end
binary_string_matches = Set.new
keg.each_unique_binary_file do |file|
binary_string_matches << file if string_matches.include?(file)
end
# Only consider string matches which are binary files with null bytes, and remove any
# matches which are sharballs found by text_files.
binary_string_matches -= text_files
# Split binary by null characters into array and substitute new cellar for old cellar.
# Null padding is added if the new string is too short.
binary_string_matches.each do |binary_file|
binary_file.ensure_writable do
binary = File.binread binary_file
puts "Replacing build prefix in: #{binary_file}"
binary_strings = binary.split(BINARY_NULL_CHARACTER)
match_indices = binary_strings.each_index.select { |i| binary_strings[i].include?(old_prefix) }
# Only perform substitution on strings which match prefix regex.
match_indices.each do |i|
s = binary_strings[i]
binary_strings[i] = s.gsub(old_prefix, new_prefix).ljust(s.size, BINARY_NULL_CHARACTER)
end
# Add back null padding at the end of the binary if needed.
patched_binary = binary_strings.join(BINARY_NULL_CHARACTER).ljust(binary.size, BINARY_NULL_CHARACTER)
if patched_binary.size != binary.size
raise "Patching failed! Original and patched binary sizes do not match."
end
binary_file.atomic_write patched_binary
end
codesign_patched_binary(binary_file)
end
end
def detect_cxx_stdlibs(_options = {})
[]
end
@ -173,6 +217,14 @@ class Keg
end
alias generic_recursive_fgrep_args recursive_fgrep_args
def egrep_args
grep_bin = "grep"
grep_args = recursive_fgrep_args
grep_args += "Pa"
[grep_bin, grep_args]
end
alias generic_egrep_args egrep_args
def each_unique_file_matching(string)
Utils.popen_read("fgrep", recursive_fgrep_args, string, to_s) do |io|
hardlinks = Set.new
@ -186,6 +238,26 @@ class Keg
end
end
def each_unique_binary_file
grep_bin, grep_args = egrep_args
# An extra \ is needed for the null character when calling grep
Utils.popen_read(grep_bin, grep_args, "\\x00", to_s) do |io|
hardlinks = Set.new
until io.eof?
file = Pathname.new(io.readline.chomp)
next if file.symlink?
yield file if hardlinks.add? file.stat.ino
end
end
end
def codesign_patched_binary(_binary_file)
[]
end
def lib
path/"lib"
end