From 2476801613a293d7810c5faf2e3383a653b1389c Mon Sep 17 00:00:00 2001 From: Misty De Meo Date: Sun, 17 Mar 2013 13:30:12 -0500 Subject: [PATCH] Hardware: separate out CPU values into CPU module * CPU functions now exist in Hardware::CPU * Added compatibility functions in compat/hardware_compat.rb * Names are less specific to Mac hardware, e.g. CPU.family instead of Hardware.intel_family * Hardware::CPU.family works for both Intel and PowerPC * New helper methods on CPU, like .sse4? and .altivec? Signed-off-by: Misty De Meo --- Library/Homebrew/cmd/--config.rb | 2 +- Library/Homebrew/compat/hardware_compat.rb | 29 ++++++ Library/Homebrew/extend/ENV.rb | 19 ++-- Library/Homebrew/hardware.rb | 40 ++++++-- Library/Homebrew/macos.rb | 3 + Library/Homebrew/os/linux/hardware.rb | 22 +++-- Library/Homebrew/os/mac/hardware.rb | 102 ++++++++++++++------- Library/Homebrew/test/test_hardware.rb | 4 +- 8 files changed, 162 insertions(+), 59 deletions(-) create mode 100644 Library/Homebrew/compat/hardware_compat.rb diff --git a/Library/Homebrew/cmd/--config.rb b/Library/Homebrew/cmd/--config.rb index 6f6368291a..1143d5d00e 100644 --- a/Library/Homebrew/cmd/--config.rb +++ b/Library/Homebrew/cmd/--config.rb @@ -85,7 +85,7 @@ module Homebrew extend self end def hardware - "CPU: #{Hardware.cores_as_words}-core #{Hardware.bits}-bit #{Hardware.intel_family}" + "CPU: #{Hardware.cores_as_words}-core #{Hardware::CPU.bits}-bit #{Hardware::CPU.family}" end def kernel diff --git a/Library/Homebrew/compat/hardware_compat.rb b/Library/Homebrew/compat/hardware_compat.rb new file mode 100644 index 0000000000..550c10118d --- /dev/null +++ b/Library/Homebrew/compat/hardware_compat.rb @@ -0,0 +1,29 @@ +class Hardware + class << self + def is_32_bit? + not CPU.is_64_bit? + end + + def is_64_bit? + CPU.is_64_bit? + end + + def bits + Hardware::CPU.bits + end + + def cpu_type + Hardware::CPU.type + end + + def cpu_family + Hardware::CPU.family + end + alias_method :intel_family, :cpu_family + alias_method :ppc_family, :cpu_family + + def processor_count + Hardware::CPU.cores + end + end +end diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb index 0f93a5d6f0..097f002d2d 100644 --- a/Library/Homebrew/extend/ENV.rb +++ b/Library/Homebrew/extend/ENV.rb @@ -121,7 +121,8 @@ module HomebrewEnvExtension self['CC'] = self['OBJC'] = "#{MacOS.dev_tools_path}/gcc-4.0" self['CXX'] = self['OBJCXX'] = "#{MacOS.dev_tools_path}/g++-4.0" replace_in_cflags '-O4', '-O3' - set_cpu_cflags 'nocona -mssse3', :core => 'prescott', :bottle => 'generic' + set_cpu_cflags '-march=nocona -mssse3', + Hardware::CPU.optimization_flags @compiler = :gcc end alias_method :gcc_4_0, :gcc_4_0_1 @@ -155,7 +156,7 @@ module HomebrewEnvExtension end replace_in_cflags '-O4', '-O3' - set_cpu_cflags 'core2 -msse4', :penryn => 'core2 -msse4.1', :core2 => 'core2', :core => 'prescott', :bottle => 'generic' + set_cpu_cflags '-march=core2 -msse4', Hardware::CPU.optimization_flags @compiler = :gcc end alias_method :gcc_4_2, :gcc @@ -163,7 +164,7 @@ module HomebrewEnvExtension def llvm self['CC'] = self['OBJC'] = MacOS.locate("llvm-gcc") self['CXX'] = self['OBJCXX'] = MacOS.locate("llvm-g++") - set_cpu_cflags 'core2 -msse4', :penryn => 'core2 -msse4.1', :core2 => 'core2', :core => 'prescott' + set_cpu_cflags '-march=core2 -msse4', Hardware::CPU.optimization_flags @compiler = :llvm end @@ -172,7 +173,7 @@ module HomebrewEnvExtension self['CXX'] = self['OBJCXX'] = MacOS.locate("clang++") replace_in_cflags(/-Xarch_i386 (-march=\S*)/, '\1') # Clang mistakenly enables AES-NI on plain Nehalem - set_cpu_cflags 'native', :nehalem => 'native -Xclang -target-feature -Xclang -aes' + set_cpu_cflags '-march=native', :nehalem => '-march=native -Xclang -target-feature -Xclang -aes' append_to_cflags '-Qunused-arguments' @compiler = :clang end @@ -325,10 +326,10 @@ module HomebrewEnvExtension append flags, xarch unless xarch.empty? if ARGV.build_bottle? - append flags, '-mtune=' + map.fetch(:bottle) if map.has_key? :bottle + append flags, '-mtune=generic' else # Don't set -msse3 and older flags because -march does that for us - append flags, '-march=' + map.fetch(Hardware.intel_family, default) + append flags, map.fetch(Hardware::CPU.family, default) end # not really a 'CPU' cflag, but is only used with clang @@ -467,7 +468,8 @@ class << ENV flags_to_set.each {|key| self[key] = cflags} # Ensure we use architecture optimizations for GCC 4.2.x - set_cpu_flags flags_to_set, 'core2 -msse4', :penryn => 'core2 -msse4.1', :core2 => 'core2', :core => 'prescott', :bottle => 'generic' + set_cpu_flags flags_to_set, 'core2 -msse4', + Hardware::CPU.optimization_flags elsif not self['FCFLAGS'] or self['FFLAGS'] opoo <<-EOS.undent No Fortran optimization information was provided. You may want to consider @@ -487,7 +489,8 @@ class << ENV fc_flag_vars.each {|key| self[key] = cflags} # Ensure we use architecture optimizations for GCC 4.2.x - set_cpu_flags fc_flag_vars, 'core2 -msse4', :penryn => 'core2 -msse4.1', :core2 => 'core2', :core => 'prescott', :bottle => 'generic' + set_cpu_flags fc_flag_vars, 'core2 -msse4', + Hardware::CPU.optimization_flags else onoe <<-EOS diff --git a/Library/Homebrew/hardware.rb b/Library/Homebrew/hardware.rb index ded0c9ccb3..b139215aee 100644 --- a/Library/Homebrew/hardware.rb +++ b/Library/Homebrew/hardware.rb @@ -1,11 +1,39 @@ +require 'hardware_compat' + class Hardware + module CPU extend self + def type + @type || :dunno + end + + def family + @family || :dunno + end + + def cores + @cores || 1 + end + + def bits + @bits || 64 + end + + def is_32_bit? + bits == 32 + end + + def is_64_bit? + bits == 64 + end + end + case RUBY_PLATFORM.downcase when /darwin/ require 'os/mac/hardware' - extend MacOSHardware + CPU.extend MacCPUs when /linux/ require 'os/linux/hardware' - extend LinuxHardware + CPU.extend LinuxCPUs else raise "The system `#{`uname`.chomp}' is not supported." end @@ -19,12 +47,4 @@ class Hardware Hardware.processor_count end end - - def self.is_32_bit? - not self.is_64_bit? - end - - def self.bits - Hardware.is_64_bit? ? 64 : 32 - end end diff --git a/Library/Homebrew/macos.rb b/Library/Homebrew/macos.rb index e94ba62c93..e073eb07ea 100644 --- a/Library/Homebrew/macos.rb +++ b/Library/Homebrew/macos.rb @@ -9,6 +9,9 @@ module MacOS extend self end def cat + # PowerPC builds per processor, not per OS + return Hardware::CPU.family if Hardware::CPU.type == :ppc + if version == :mountain_lion then :mountain_lion elsif version == :lion then :lion elsif version == :snow_leopard diff --git a/Library/Homebrew/os/linux/hardware.rb b/Library/Homebrew/os/linux/hardware.rb index 8fd4b09b96..9dc454956d 100644 --- a/Library/Homebrew/os/linux/hardware.rb +++ b/Library/Homebrew/os/linux/hardware.rb @@ -1,6 +1,9 @@ -module LinuxHardware - def cpu_type - @@cpu_type ||= case `uname -m` +module LinuxCPUs + OPTIMIZATION_FLAGS = {} + def optimization_flags; OPTIMIZATION_FLAGS.dup; end + + def type + @cpu_type ||= case `uname -m` when /x86_64/ :intel when /i386/ @@ -10,16 +13,21 @@ module LinuxHardware end end - def intel_family + def family :dunno end + alias_method :intel_family, :cpu_family - def processor_count + def cores `grep -c ^processor /proc/cpuinfo`.to_i end + def bits + is_64_bit? ? 64 : 32 + end + def is_64_bit? - return @@is_64_bit if defined? @@is_64_bit - @@is_64_bit = /64/ === `uname -m` + return @is_64_bit if defined? @is_64_bit + @is_64_bit = /64/ === `uname -m` end end diff --git a/Library/Homebrew/os/mac/hardware.rb b/Library/Homebrew/os/mac/hardware.rb index ffdc6246c3..e70ce7b8a5 100644 --- a/Library/Homebrew/os/mac/hardware.rb +++ b/Library/Homebrew/os/mac/hardware.rb @@ -1,10 +1,20 @@ -module MacOSHardware +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' + } + def optimization_flags; OPTIMIZATION_FLAGS.dup; end + # These methods use info spewed out by sysctl. # Look in for decoding info. - def cpu_type - @@cpu_type ||= `/usr/sbin/sysctl -n hw.cputype`.to_i - - case @@cpu_type + def type + @type ||= `/usr/sbin/sysctl -n hw.cputype`.to_i + case @type when 7 :intel when 18 @@ -14,39 +24,69 @@ module MacOSHardware end end - def intel_family - @@intel_family ||= `/usr/sbin/sysctl -n hw.cpufamily`.to_i - - case @@intel_family - 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 - else - :dunno + def family + if type == :intel + @intel_family ||= `/usr/sbin/sysctl -n hw.cpufamily`.to_i + case @intel_family + 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 + else + :dunno + end + elsif type == :ppc + @ppc_family ||= `/usr/sbin/sysctl -n hw.cpusubtype`.to_i + case @ppc_family + when 9 + :g3 # PowerPC 750 + when 10 + :g4 # PowerPC 7400 + when 11 + :g4e # PowerPC 7450 + when 100 + :g5 # PowerPC 970 + else + :dunno + end end end - def processor_count - @@processor_count ||= `/usr/sbin/sysctl -n hw.ncpu`.to_i + def cores + @cores ||= `/usr/sbin/sysctl -n hw.ncpu`.to_i end - def is_64_bit? - return @@is_64_bit if defined? @@is_64_bit - @@is_64_bit = sysctl_bool("hw.cpu64bit_capable") + def bits + return @bits if defined? @bits + + is_64_bit = sysctl_bool("hw.cpu64bit_capable") + @bits ||= is_64_bit ? 64 : 32 end -protected + def altivec? + type == :ppc && family != :g3 + end + + def sse3? + type == :intel + end + + def sse4? + type == :intel && (family != :core && family != :core2) + end + + protected + def sysctl_bool(property) result = nil IO.popen("/usr/sbin/sysctl -n #{property} 2>/dev/null") do |f| diff --git a/Library/Homebrew/test/test_hardware.rb b/Library/Homebrew/test/test_hardware.rb index ab55826f9a..2f9787c9c5 100644 --- a/Library/Homebrew/test/test_hardware.rb +++ b/Library/Homebrew/test/test_hardware.rb @@ -5,13 +5,13 @@ class HardwareTests < Test::Unit::TestCase # these will raise if we don't recognise your mac, but that prolly # indicates something went wrong rather than we don't know def test_hardware_cpu_type - assert [:intel, :ppc].include?(Hardware.cpu_type) + assert [:intel, :ppc].include?(Hardware::CPU.type) end def test_hardware_intel_family if Hardware.cpu_type == :intel assert [:core, :core2, :penryn, :nehalem, - :arrandale, :sandybridge, :ivybridge].include?(Hardware.intel_family) + :arrandale, :sandybridge, :ivybridge].include?(Hardware::CPU.family) end end end