require 'mach' module MacCPUs OPTIMIZATION_FLAGS = { :penryn => '-march=core2 -msse4.1', :core2 => '-march=core2', :core => '-march=prescott', :g3 => '-mcpu=750', :g4 => '-mcpu=7400', :g4e => '-mcpu=7450', :g5 => '-mcpu=970' }.freeze def optimization_flags; OPTIMIZATION_FLAGS; end # These methods use info spewed out by sysctl. # Look in for decoding info. def type @type ||= `/usr/sbin/sysctl -n hw.cputype`.to_i case @type when 7 :intel when 18 :ppc else :dunno end end def family if intel? case @intel_family ||= `/usr/sbin/sysctl -n hw.cpufamily`.to_i when 0x73d67300 # Yonah: Core Solo/Duo :core when 0x426f69ef # Merom: Core 2 Duo :core2 when 0x78ea4fbc # Penryn :penryn when 0x6b5a4cd2 # Nehalem :nehalem when 0x573B5EEC # Arrandale :arrandale when 0x5490B78C # Sandy Bridge :sandybridge when 0x1F65E835 # Ivy Bridge :ivybridge when 0x10B282DC # Haswell :haswell else :dunno end elsif ppc? case @ppc_family ||= `/usr/sbin/sysctl -n hw.cpusubtype`.to_i when 9 :g3 # PowerPC 750 when 10 :g4 # PowerPC 7400 when 11 :g4e # PowerPC 7450 when 100 # This is the only 64-bit PPC CPU type, so it's useful # to distinguish in `brew --config` output and in bottle tags MacOS.prefer_64_bit? ? :g5_64 : :g5 # PowerPC 970 else :dunno end end end def extmodel @extmodel ||= `/usr/sbin/sysctl -n machdep.cpu.extmodel`.to_i end def cores @cores ||= `/usr/sbin/sysctl -n hw.ncpu`.to_i end def bits @bits ||= sysctl_bool("hw.cpu64bit_capable") ? 64 : 32 end def arch_32_bit intel? ? :i386 : :ppc end def arch_64_bit intel? ? :x86_64 : :ppc64 end # Returns an array that's been extended with ArchitectureListExtension, # which provides helpers like #as_arch_flags and #as_cmake_arch_flags. def universal_archs # Building 64-bit is a no-go on Tiger, and pretty hit or miss on Leopard. # Don't even try unless Tigerbrew's experimental 64-bit Leopard support is enabled. if MacOS.version <= :leopard and !MacOS.prefer_64_bit? [arch_32_bit].extend ArchitectureListExtension else [arch_32_bit, arch_64_bit].extend ArchitectureListExtension end end def aes? sysctl_bool('hw.optional.aes') end def altivec? sysctl_bool('hw.optional.altivec') end def avx? sysctl_bool('hw.optional.avx1_0') end def avx2? sysctl_bool('hw.optional.avx2_0') end def sse3? sysctl_bool('hw.optional.sse3') end def ssse3? sysctl_bool('hw.optional.supplementalsse3') end def sse4? sysctl_bool('hw.optional.sse4_1') end def sse4_2? sysctl_bool('hw.optional.sse4_2') end protected def sysctl_bool(property) (@properties ||= {}).fetch(property) do result = nil IO.popen("/usr/sbin/sysctl -n '#{property}' 2>/dev/null") do |f| result = f.gets.to_i # should be 0 or 1 end # sysctl call succeded and printed 1 @properties[property] = $?.success? && result == 1 end end end