Module: OS::Linux::Keg Private
- Extended by:
- T::Helpers
- Included in:
- Keg
- Defined in:
- extend/os/linux/keg.rb,
extend/os/linux/keg_relocate.rb
This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
- #binary_executable_or_library_files ⇒ Array<ELFShim> private
- #change_rpath!(file, old_prefix, new_prefix, with_placeholders: false) ⇒ Boolean private
- #detect_cxx_stdlibs(options = {}) ⇒ Array<Symbol> private
- #elf_files ⇒ Array<ELFShim> private
- #relocate_dynamic_linkage(relocation, with_placeholders: false, files: nil) ⇒ Array<::Pathname> private
Instance Method Details
#binary_executable_or_library_files ⇒ Array<ELFShim>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
8 |
# File 'extend/os/linux/keg.rb', line 8 def binary_executable_or_library_files = elf_files |
#change_rpath!(file, old_prefix, new_prefix, with_placeholders: false) ⇒ Boolean
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'extend/os/linux/keg_relocate.rb', line 55 def change_rpath!(file, old_prefix, new_prefix, with_placeholders: false) return false if !file.elf? || !file.dynamic_elf? # Skip relocation of files with `protodesc_cold` sections because patchelf.rb seems to break them, # but only when bottling (as we don't want to break existing bottles that require relocation). # https://github.com/Homebrew/homebrew-core/pull/232490#issuecomment-3161362452 # Also skip relocation of files with `.bun` sections return false if with_placeholders && file.section_names.intersect?(["protodesc_cold", ".bun"]) updated = {} old_rpath = file.rpath new_rpath = if old_rpath rpath = old_rpath.split(":") .map { |x| x.sub(old_prefix, new_prefix) } .select { |x| x.start_with?(new_prefix, "$ORIGIN") } lib_path = "#{new_prefix}/lib" rpath << lib_path unless rpath.include? lib_path # Add GCC's lib directory (as of GCC 12+) to RPATH when there is existing versioned linkage. # This prevents broken linkage when pouring bottles built with an old GCC formula. unless name.match?(Version.formula_optionally_versioned_regex(:gcc)) rpath.map! { |rp| rp.sub(%r{lib/gcc/\d+$}, "lib/gcc/current") } end rpath.join(":") end updated[:rpath] = new_rpath if old_rpath != new_rpath old_interpreter = file.interpreter new_interpreter = if old_interpreter.nil? nil elsif File.readable? "#{new_prefix}/lib/ld.so" "#{new_prefix}/lib/ld.so" else old_interpreter.sub old_prefix, new_prefix end updated[:interpreter] = new_interpreter if old_interpreter != new_interpreter return false if updated.empty? file.patch!(interpreter: updated[:interpreter], rpath: updated[:rpath]) require_relocation! true end |
#detect_cxx_stdlibs(options = {}) ⇒ Array<Symbol>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'extend/os/linux/keg_relocate.rb', line 101 def detect_cxx_stdlibs( = {}) skip_executables = .fetch(:skip_executables, false) results = Set.new elf_files.each do |file| next unless file.dynamic_elf? next if file.binary_executable? && skip_executables dylibs = file.dynamically_linked_libraries results << :libcxx if dylibs.any? { |s| s.include? "libc++.so" } results << :libstdcxx if dylibs.any? { |s| s.include? "libstdc++.so" } end results.to_a end |
#elf_files ⇒ Array<ELFShim>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'extend/os/linux/keg_relocate.rb', line 116 def elf_files hardlinks = Set.new elf_files = [] path.find do |pn| next if pn.symlink? || pn.directory? pn = ELFPathname.wrap(pn) next if !pn.dylib? && !pn.binary_executable? # If we've already processed a file, ignore its hardlinks (which have the # same dev ID and inode). This prevents relocations from being performed # on a binary more than once. next unless hardlinks.add? [pn.stat.dev, pn.stat.ino] elf_files << pn end elf_files end |
#relocate_dynamic_linkage(relocation, with_placeholders: false, files: nil) ⇒ Array<::Pathname>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'extend/os/linux/keg_relocate.rb', line 26 def relocate_dynamic_linkage(relocation, with_placeholders: false, files: nil) # Patching the dynamic linker of glibc breaks it. return [] if name.match? Version.formula_optionally_versioned_regex(:glibc) old_prefix, new_prefix = relocation.replacement_pair_for(:prefix) candidates = if files # Metadata-driven pour: only the files recorded at bottle time carry # placeholdered linkage, so skip the whole-keg walk. keg_files(files).map { |file| ELFPathname.wrap(file) } else elf_files end linkage_files = [] candidates.each do |file| changed = T.let(false, T::Boolean) Utils::Path.ensure_writable(file.to_path) do changed = change_rpath!(file, old_prefix, new_prefix, with_placeholders:) end linkage_files << file.relative_path_from(path) if changed end linkage_files end |