From 646f94adfef333c9ec5451fca55078de06ada3c0 Mon Sep 17 00:00:00 2001 From: Xu Cheng Date: Fri, 16 Oct 2015 17:08:11 +0800 Subject: move mach.rb to os/mac/mach.rb --- Library/Homebrew/extend/pathname.rb | 3 - Library/Homebrew/mach.rb | 204 ------------------------------------ Library/Homebrew/os/mac.rb | 1 + Library/Homebrew/os/mac/hardware.rb | 2 +- Library/Homebrew/os/mac/mach.rb | 204 ++++++++++++++++++++++++++++++++++++ Library/Homebrew/os/mac/pathname.rb | 5 + 6 files changed, 211 insertions(+), 208 deletions(-) delete mode 100644 Library/Homebrew/mach.rb create mode 100644 Library/Homebrew/os/mac/mach.rb create mode 100644 Library/Homebrew/os/mac/pathname.rb (limited to 'Library') diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index 95002d20f..9708879e9 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -1,13 +1,10 @@ require "pathname" -require "mach" require "resource" require "metafiles" # Homebrew extends Ruby's `Pathname` to make our code more readable. # @see http://ruby-doc.org/stdlib-1.8.7/libdoc/pathname/rdoc/Pathname.html Ruby's Pathname API class Pathname - include MachO - # @private BOTTLE_EXTNAME_RX = /(\.[a-z0-9_]+\.bottle\.(\d+\.)?tar\.gz)$/ diff --git a/Library/Homebrew/mach.rb b/Library/Homebrew/mach.rb deleted file mode 100644 index 49382291c..000000000 --- a/Library/Homebrew/mach.rb +++ /dev/null @@ -1,204 +0,0 @@ -module ArchitectureListExtension - # @private - def fat? - length > 1 - end - - # @private - def intel_universal? - intersects_all?(Hardware::CPU::INTEL_32BIT_ARCHS, Hardware::CPU::INTEL_64BIT_ARCHS) - end - - # @private - def ppc_universal? - intersects_all?(Hardware::CPU::PPC_32BIT_ARCHS, Hardware::CPU::PPC_64BIT_ARCHS) - end - - # Old-style 32-bit PPC/Intel universal, e.g. ppc7400 and i386 - # @private - def cross_universal? - intersects_all?(Hardware::CPU::PPC_32BIT_ARCHS, Hardware::CPU::INTEL_32BIT_ARCHS) - end - - # @private - def universal? - intel_universal? || ppc_universal? || cross_universal? - end - - def ppc? - (Hardware::CPU::PPC_32BIT_ARCHS+Hardware::CPU::PPC_64BIT_ARCHS).any? { |a| self.include? a } - end - - # @private - def remove_ppc! - (Hardware::CPU::PPC_32BIT_ARCHS+Hardware::CPU::PPC_64BIT_ARCHS).each { |a| delete a } - end - - def as_arch_flags - collect { |a| "-arch #{a}" }.join(" ") - end - - def as_cmake_arch_flags - join(";") - end - - protected - - def intersects_all?(*set) - set.all? do |archset| - archset.any? { |a| self.include? a } - end - end -end - -module MachO - # @private - OTOOL_RX = /\t(.*) \(compatibility version (?:\d+\.)*\d+, current version (?:\d+\.)*\d+\)/ - - # Mach-O binary methods, see: - # /usr/include/mach-o/loader.h - # /usr/include/mach-o/fat.h - # @private - def mach_data - @mach_data ||= begin - offsets = [] - mach_data = [] - - header = read(8).unpack("N2") - case header[0] - when 0xcafebabe # universal - header[1].times do |i| - # header[1] is the number of struct fat_arch in the file. - # Each struct fat_arch is 20 bytes, and the 'offset' member - # begins 8 bytes into the struct, with an additional 8 byte - # offset due to the struct fat_header at the beginning of - # the file. - offsets << read(4, 20*i + 16).unpack("N")[0] - end - when 0xcefaedfe, 0xcffaedfe, 0xfeedface, 0xfeedfacf # Single arch - offsets << 0 - when 0x7f454c46 # ELF - mach_data << { :arch => :x86_64, :type => :executable } - else - raise "Not a Mach-O binary." - end - - offsets.each do |offset| - arch = case read(8, offset).unpack("N2") - when [0xcefaedfe, 0x07000000] then :i386 - when [0xcffaedfe, 0x07000001] then :x86_64 - when [0xfeedface, 0x00000012] then :ppc7400 - when [0xfeedfacf, 0x01000012] then :ppc64 - else :dunno - end - - type = case read(4, offset + 12).unpack("N")[0] - when 0x00000002, 0x02000000 then :executable - when 0x00000006, 0x06000000 then :dylib - when 0x00000008, 0x08000000 then :bundle - else :dunno - end - - mach_data << { :arch => arch, :type => type } - end - mach_data - rescue - [] - end - end - - def archs - mach_data.map { |m| m.fetch :arch }.extend(ArchitectureListExtension) - end - - def arch - case archs.length - when 0 then :dunno - when 1 then archs.first - else :universal - end - end - - def universal? - arch == :universal - end - - def i386? - arch == :i386 - end - - def x86_64? - arch == :x86_64 - end - - def ppc7400? - arch == :ppc7400 - end - - def ppc64? - arch == :ppc64 - end - - # @private - def dylib? - mach_data.any? { |m| m.fetch(:type) == :dylib } - end - - # @private - def mach_o_executable? - mach_data.any? { |m| m.fetch(:type) == :executable } - end - - # @private - def mach_o_bundle? - mach_data.any? { |m| m.fetch(:type) == :bundle } - end - - # @private - class Metadata - attr_reader :path, :dylib_id, :dylibs - - def initialize(path) - @path = path - @dylib_id, @dylibs = parse_otool_L_output - end - - def parse_otool_L_output - ENV["HOMEBREW_MACH_O_FILE"] = path.expand_path.to_s - libs = `#{MacOS.otool} -L "$HOMEBREW_MACH_O_FILE"`.split("\n") - unless $?.success? - raise ErrorDuringExecution.new(MacOS.otool, - ["-L", ENV["HOMEBREW_MACH_O_FILE"]]) - end - - libs.shift # first line is the filename - - id = libs.shift[OTOOL_RX, 1] if path.dylib? - libs.map! { |lib| lib[OTOOL_RX, 1] }.compact! - - return id, libs - ensure - ENV.delete "HOMEBREW_MACH_O_FILE" - end - end - - # @private - def mach_metadata - @mach_metadata ||= Metadata.new(self) - end - - # Returns an array containing all dynamically-linked libraries, based on the - # output of otool. This returns the install names, so these are not guaranteed - # to be absolute paths. - # Returns an empty array both for software that links against no libraries, - # and for non-mach objects. - # @private - def dynamically_linked_libraries - mach_metadata.dylibs - end - - # @private - def dylib_id - mach_metadata.dylib_id - end -end diff --git a/Library/Homebrew/os/mac.rb b/Library/Homebrew/os/mac.rb index 691f92b51..3568f7158 100644 --- a/Library/Homebrew/os/mac.rb +++ b/Library/Homebrew/os/mac.rb @@ -2,6 +2,7 @@ require "hardware" require "os/mac/version" require "os/mac/xcode" require "os/mac/xquartz" +require "os/mac/pathname" module OS module Mac diff --git a/Library/Homebrew/os/mac/hardware.rb b/Library/Homebrew/os/mac/hardware.rb index db4fe5875..5643416c8 100644 --- a/Library/Homebrew/os/mac/hardware.rb +++ b/Library/Homebrew/os/mac/hardware.rb @@ -1,4 +1,4 @@ -require "mach" +require "os/mac/mach" module MacCPUs OPTIMIZATION_FLAGS = { diff --git a/Library/Homebrew/os/mac/mach.rb b/Library/Homebrew/os/mac/mach.rb new file mode 100644 index 000000000..49382291c --- /dev/null +++ b/Library/Homebrew/os/mac/mach.rb @@ -0,0 +1,204 @@ +module ArchitectureListExtension + # @private + def fat? + length > 1 + end + + # @private + def intel_universal? + intersects_all?(Hardware::CPU::INTEL_32BIT_ARCHS, Hardware::CPU::INTEL_64BIT_ARCHS) + end + + # @private + def ppc_universal? + intersects_all?(Hardware::CPU::PPC_32BIT_ARCHS, Hardware::CPU::PPC_64BIT_ARCHS) + end + + # Old-style 32-bit PPC/Intel universal, e.g. ppc7400 and i386 + # @private + def cross_universal? + intersects_all?(Hardware::CPU::PPC_32BIT_ARCHS, Hardware::CPU::INTEL_32BIT_ARCHS) + end + + # @private + def universal? + intel_universal? || ppc_universal? || cross_universal? + end + + def ppc? + (Hardware::CPU::PPC_32BIT_ARCHS+Hardware::CPU::PPC_64BIT_ARCHS).any? { |a| self.include? a } + end + + # @private + def remove_ppc! + (Hardware::CPU::PPC_32BIT_ARCHS+Hardware::CPU::PPC_64BIT_ARCHS).each { |a| delete a } + end + + def as_arch_flags + collect { |a| "-arch #{a}" }.join(" ") + end + + def as_cmake_arch_flags + join(";") + end + + protected + + def intersects_all?(*set) + set.all? do |archset| + archset.any? { |a| self.include? a } + end + end +end + +module MachO + # @private + OTOOL_RX = /\t(.*) \(compatibility version (?:\d+\.)*\d+, current version (?:\d+\.)*\d+\)/ + + # Mach-O binary methods, see: + # /usr/include/mach-o/loader.h + # /usr/include/mach-o/fat.h + # @private + def mach_data + @mach_data ||= begin + offsets = [] + mach_data = [] + + header = read(8).unpack("N2") + case header[0] + when 0xcafebabe # universal + header[1].times do |i| + # header[1] is the number of struct fat_arch in the file. + # Each struct fat_arch is 20 bytes, and the 'offset' member + # begins 8 bytes into the struct, with an additional 8 byte + # offset due to the struct fat_header at the beginning of + # the file. + offsets << read(4, 20*i + 16).unpack("N")[0] + end + when 0xcefaedfe, 0xcffaedfe, 0xfeedface, 0xfeedfacf # Single arch + offsets << 0 + when 0x7f454c46 # ELF + mach_data << { :arch => :x86_64, :type => :executable } + else + raise "Not a Mach-O binary." + end + + offsets.each do |offset| + arch = case read(8, offset).unpack("N2") + when [0xcefaedfe, 0x07000000] then :i386 + when [0xcffaedfe, 0x07000001] then :x86_64 + when [0xfeedface, 0x00000012] then :ppc7400 + when [0xfeedfacf, 0x01000012] then :ppc64 + else :dunno + end + + type = case read(4, offset + 12).unpack("N")[0] + when 0x00000002, 0x02000000 then :executable + when 0x00000006, 0x06000000 then :dylib + when 0x00000008, 0x08000000 then :bundle + else :dunno + end + + mach_data << { :arch => arch, :type => type } + end + mach_data + rescue + [] + end + end + + def archs + mach_data.map { |m| m.fetch :arch }.extend(ArchitectureListExtension) + end + + def arch + case archs.length + when 0 then :dunno + when 1 then archs.first + else :universal + end + end + + def universal? + arch == :universal + end + + def i386? + arch == :i386 + end + + def x86_64? + arch == :x86_64 + end + + def ppc7400? + arch == :ppc7400 + end + + def ppc64? + arch == :ppc64 + end + + # @private + def dylib? + mach_data.any? { |m| m.fetch(:type) == :dylib } + end + + # @private + def mach_o_executable? + mach_data.any? { |m| m.fetch(:type) == :executable } + end + + # @private + def mach_o_bundle? + mach_data.any? { |m| m.fetch(:type) == :bundle } + end + + # @private + class Metadata + attr_reader :path, :dylib_id, :dylibs + + def initialize(path) + @path = path + @dylib_id, @dylibs = parse_otool_L_output + end + + def parse_otool_L_output + ENV["HOMEBREW_MACH_O_FILE"] = path.expand_path.to_s + libs = `#{MacOS.otool} -L "$HOMEBREW_MACH_O_FILE"`.split("\n") + unless $?.success? + raise ErrorDuringExecution.new(MacOS.otool, + ["-L", ENV["HOMEBREW_MACH_O_FILE"]]) + end + + libs.shift # first line is the filename + + id = libs.shift[OTOOL_RX, 1] if path.dylib? + libs.map! { |lib| lib[OTOOL_RX, 1] }.compact! + + return id, libs + ensure + ENV.delete "HOMEBREW_MACH_O_FILE" + end + end + + # @private + def mach_metadata + @mach_metadata ||= Metadata.new(self) + end + + # Returns an array containing all dynamically-linked libraries, based on the + # output of otool. This returns the install names, so these are not guaranteed + # to be absolute paths. + # Returns an empty array both for software that links against no libraries, + # and for non-mach objects. + # @private + def dynamically_linked_libraries + mach_metadata.dylibs + end + + # @private + def dylib_id + mach_metadata.dylib_id + end +end diff --git a/Library/Homebrew/os/mac/pathname.rb b/Library/Homebrew/os/mac/pathname.rb new file mode 100644 index 000000000..9b65d7ac0 --- /dev/null +++ b/Library/Homebrew/os/mac/pathname.rb @@ -0,0 +1,5 @@ +require "os/mac/mach" + +class Pathname + include MachO +end -- cgit v1.2.3