diff options
| author | Xu Cheng | 2015-10-16 17:08:11 +0800 |
|---|---|---|
| committer | Xu Cheng | 2015-10-18 22:57:42 +0800 |
| commit | 646f94adfef333c9ec5451fca55078de06ada3c0 (patch) | |
| tree | 01e56f025f13c5819384aed9c2ae0a634699ccb1 /Library/Homebrew/os | |
| parent | 06806f860d12aa5a4cfd077b67cae62071755864 (diff) | |
| download | brew-646f94adfef333c9ec5451fca55078de06ada3c0.tar.bz2 | |
move mach.rb to os/mac/mach.rb
Diffstat (limited to 'Library/Homebrew/os')
| -rw-r--r-- | Library/Homebrew/os/mac.rb | 1 | ||||
| -rw-r--r-- | Library/Homebrew/os/mac/hardware.rb | 2 | ||||
| -rw-r--r-- | Library/Homebrew/os/mac/mach.rb | 204 | ||||
| -rw-r--r-- | Library/Homebrew/os/mac/pathname.rb | 5 |
4 files changed, 211 insertions, 1 deletions
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 |
