mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00

IO#read does not raise EOFError, it just returns an empty string for each call after it consumes the underlying file or stream. This module is going to be refactored and the begin/rescue is going to be removed anyway.
117 lines
2.5 KiB
Ruby
117 lines
2.5 KiB
Ruby
module ArchitectureListExtension
|
|
def universal?
|
|
self.include? :i386 and self.include? :x86_64
|
|
end
|
|
|
|
def ppc?
|
|
self.include? :ppc7400 or self.include? :ppc64
|
|
end
|
|
|
|
def remove_ppc!
|
|
self.delete :ppc7400
|
|
self.delete :ppc64
|
|
end
|
|
|
|
def as_arch_flags
|
|
self.collect{ |a| "-arch #{a}" }.join(' ')
|
|
end
|
|
end
|
|
|
|
module MachO
|
|
# Mach-O binary methods, see:
|
|
# /usr/include/mach-o/loader.h
|
|
# /usr/include/mach-o/fat.h
|
|
|
|
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
|
|
|
|
def dylib?
|
|
mach_data.any? { |m| m.fetch(:type) == :dylib }
|
|
end
|
|
|
|
def mach_o_executable?
|
|
mach_data.any? { |m| m.fetch(:type) == :executable }
|
|
end
|
|
|
|
def mach_o_bundle?
|
|
mach_data.any? { |m| m.fetch(:type) == :bundle }
|
|
end
|
|
end
|