Make hardware code cross-platform.
This commit is contained in:
parent
8a582f2bd9
commit
8d995e961f
@ -1,4 +1,4 @@
|
|||||||
class Hardware
|
module Hardware
|
||||||
class << self
|
class << self
|
||||||
# We won't change the name because of backward compatibility.
|
# We won't change the name because of backward compatibility.
|
||||||
# So disable rubocop here.
|
# So disable rubocop here.
|
||||||
|
|||||||
5
Library/Homebrew/extend/os/hardware.rb
Normal file
5
Library/Homebrew/extend/os/hardware.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
if OS.mac?
|
||||||
|
require "extend/os/mac/hardware/cpu"
|
||||||
|
elsif OS.linux?
|
||||||
|
require "extend/os/linux/hardware/cpu"
|
||||||
|
end
|
||||||
67
Library/Homebrew/extend/os/linux/hardware/cpu.rb
Normal file
67
Library/Homebrew/extend/os/linux/hardware/cpu.rb
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
module Hardware
|
||||||
|
class CPU
|
||||||
|
extend self
|
||||||
|
|
||||||
|
OPTIMIZATION_FLAGS = {
|
||||||
|
:penryn => "-march=core2 -msse4.1",
|
||||||
|
:core2 => "-march=core2",
|
||||||
|
:core => "-march=prescott"
|
||||||
|
}.freeze
|
||||||
|
def optimization_flags
|
||||||
|
OPTIMIZATION_FLAGS
|
||||||
|
end
|
||||||
|
|
||||||
|
# Linux supports x86 only, and universal archs do not apply
|
||||||
|
def arch_32_bit
|
||||||
|
:i386
|
||||||
|
end
|
||||||
|
|
||||||
|
def arch_64_bit
|
||||||
|
:x86_64
|
||||||
|
end
|
||||||
|
|
||||||
|
def universal_archs
|
||||||
|
[].extend ArchitectureListExtension
|
||||||
|
end
|
||||||
|
|
||||||
|
def cpuinfo
|
||||||
|
@cpuinfo ||= File.read("/proc/cpuinfo")
|
||||||
|
end
|
||||||
|
|
||||||
|
def type
|
||||||
|
@type ||= if cpuinfo =~ /Intel|AMD/
|
||||||
|
:intel
|
||||||
|
else
|
||||||
|
:dunno
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def family
|
||||||
|
cpuinfo[/^cpu family\s*: ([0-9]+)/, 1].to_i
|
||||||
|
end
|
||||||
|
alias_method :intel_family, :family
|
||||||
|
|
||||||
|
def cores
|
||||||
|
cpuinfo.scan(/^processor/).size
|
||||||
|
end
|
||||||
|
|
||||||
|
def flags
|
||||||
|
@flags ||= cpuinfo[/^flags.*/, 0].split
|
||||||
|
end
|
||||||
|
|
||||||
|
# Compatibility with Mac method, which returns lowercase symbols
|
||||||
|
# instead of strings
|
||||||
|
def features
|
||||||
|
@features ||= flags[1..-1].map(&:intern)
|
||||||
|
end
|
||||||
|
|
||||||
|
%w[aes altivec avx avx2 lm sse3 ssse3 sse4 sse4_2].each do |flag|
|
||||||
|
define_method(flag + "?") { flags.include? flag }
|
||||||
|
end
|
||||||
|
alias_method :is_64_bit?, :lm?
|
||||||
|
|
||||||
|
def bits
|
||||||
|
is_64_bit? ? 64 : 32
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
171
Library/Homebrew/extend/os/mac/hardware/cpu.rb
Normal file
171
Library/Homebrew/extend/os/mac/hardware/cpu.rb
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
require "os/mac/pathname"
|
||||||
|
|
||||||
|
module Hardware
|
||||||
|
class CPU
|
||||||
|
class << self
|
||||||
|
|
||||||
|
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",
|
||||||
|
:g5_64 => "-mcpu=970 -arch ppc64"
|
||||||
|
}.freeze
|
||||||
|
def optimization_flags
|
||||||
|
OPTIMIZATION_FLAGS
|
||||||
|
end
|
||||||
|
|
||||||
|
# These methods use info spewed out by sysctl.
|
||||||
|
# Look in <mach/machine.h> for decoding info.
|
||||||
|
def type
|
||||||
|
case sysctl_int("hw.cputype")
|
||||||
|
when 7
|
||||||
|
:intel
|
||||||
|
when 18
|
||||||
|
:ppc
|
||||||
|
else
|
||||||
|
:dunno
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def family
|
||||||
|
if intel?
|
||||||
|
case sysctl_int("hw.cpufamily")
|
||||||
|
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
|
||||||
|
when 0x582ed09c # Broadwell
|
||||||
|
:broadwell
|
||||||
|
when 0x37fc219f # Skylake
|
||||||
|
:skylake
|
||||||
|
else
|
||||||
|
:dunno
|
||||||
|
end
|
||||||
|
elsif ppc?
|
||||||
|
case sysctl_int("hw.cpusubtype")
|
||||||
|
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
|
||||||
|
sysctl_int("machdep.cpu.extmodel")
|
||||||
|
end
|
||||||
|
|
||||||
|
def cores
|
||||||
|
sysctl_int("hw.ncpu")
|
||||||
|
end
|
||||||
|
|
||||||
|
def 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 && !MacOS.prefer_64_bit?
|
||||||
|
[arch_32_bit].extend ArchitectureListExtension
|
||||||
|
else
|
||||||
|
# Amazingly, this order (64, then 32) matters. It shouldn't, but it
|
||||||
|
# does. GCC (some versions? some systems?) can blow up if the other
|
||||||
|
# order is used.
|
||||||
|
# http://superuser.com/questions/740563/gcc-4-8-on-macos-fails-depending-on-arch-order
|
||||||
|
[arch_64_bit, arch_32_bit].extend ArchitectureListExtension
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def features
|
||||||
|
@features ||= sysctl_n(
|
||||||
|
"machdep.cpu.features",
|
||||||
|
"machdep.cpu.extfeatures",
|
||||||
|
"machdep.cpu.leaf7_features"
|
||||||
|
).split(" ").map { |s| s.downcase.to_sym }
|
||||||
|
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
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def sysctl_bool(key)
|
||||||
|
sysctl_int(key) == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
def sysctl_int(key)
|
||||||
|
sysctl_n(key).to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def sysctl_n(*keys)
|
||||||
|
(@properties ||= {}).fetch(keys) do
|
||||||
|
@properties[keys] = Utils.popen_read("/usr/sbin/sysctl", "-n", *keys)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -1,13 +1,13 @@
|
|||||||
require "os"
|
require "os"
|
||||||
|
|
||||||
class Hardware
|
module Hardware
|
||||||
module CPU
|
class CPU
|
||||||
extend self
|
|
||||||
INTEL_32BIT_ARCHS = [:i386].freeze
|
INTEL_32BIT_ARCHS = [:i386].freeze
|
||||||
INTEL_64BIT_ARCHS = [:x86_64].freeze
|
INTEL_64BIT_ARCHS = [:x86_64].freeze
|
||||||
PPC_32BIT_ARCHS = [:ppc, :ppc7400, :ppc7450, :ppc970].freeze
|
PPC_32BIT_ARCHS = [:ppc, :ppc7400, :ppc7450, :ppc970].freeze
|
||||||
PPC_64BIT_ARCHS = [:ppc64].freeze
|
PPC_64BIT_ARCHS = [:ppc64].freeze
|
||||||
|
|
||||||
|
class << self
|
||||||
def type
|
def type
|
||||||
:dunno
|
:dunno
|
||||||
end
|
end
|
||||||
@ -48,13 +48,6 @@ class Hardware
|
|||||||
features.include?(name)
|
features.include?(name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if OS.mac?
|
|
||||||
require "os/mac/hardware"
|
|
||||||
CPU.extend MacCPUs
|
|
||||||
elsif OS.linux?
|
|
||||||
require "os/linux/hardware"
|
|
||||||
CPU.extend LinuxCPUs
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.cores_as_words
|
def self.cores_as_words
|
||||||
@ -79,3 +72,5 @@ class Hardware
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
require "extend/os/hardware"
|
||||||
|
|||||||
@ -1,63 +0,0 @@
|
|||||||
module LinuxCPUs
|
|
||||||
OPTIMIZATION_FLAGS = {
|
|
||||||
:penryn => "-march=core2 -msse4.1",
|
|
||||||
:core2 => "-march=core2",
|
|
||||||
:core => "-march=prescott"
|
|
||||||
}.freeze
|
|
||||||
def optimization_flags
|
|
||||||
OPTIMIZATION_FLAGS
|
|
||||||
end
|
|
||||||
|
|
||||||
# Linux supports x86 only, and universal archs do not apply
|
|
||||||
def arch_32_bit
|
|
||||||
:i386
|
|
||||||
end
|
|
||||||
|
|
||||||
def arch_64_bit
|
|
||||||
:x86_64
|
|
||||||
end
|
|
||||||
|
|
||||||
def universal_archs
|
|
||||||
[].extend ArchitectureListExtension
|
|
||||||
end
|
|
||||||
|
|
||||||
def cpuinfo
|
|
||||||
@cpuinfo ||= File.read("/proc/cpuinfo")
|
|
||||||
end
|
|
||||||
|
|
||||||
def type
|
|
||||||
@type ||= if cpuinfo =~ /Intel|AMD/
|
|
||||||
:intel
|
|
||||||
else
|
|
||||||
:dunno
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def family
|
|
||||||
cpuinfo[/^cpu family\s*: ([0-9]+)/, 1].to_i
|
|
||||||
end
|
|
||||||
alias_method :intel_family, :family
|
|
||||||
|
|
||||||
def cores
|
|
||||||
cpuinfo.scan(/^processor/).size
|
|
||||||
end
|
|
||||||
|
|
||||||
def flags
|
|
||||||
@flags ||= cpuinfo[/^flags.*/, 0].split
|
|
||||||
end
|
|
||||||
|
|
||||||
# Compatibility with Mac method, which returns lowercase symbols
|
|
||||||
# instead of strings
|
|
||||||
def features
|
|
||||||
@features ||= flags[1..-1].map(&:intern)
|
|
||||||
end
|
|
||||||
|
|
||||||
%w[aes altivec avx avx2 lm sse3 ssse3 sse4 sse4_2].each do |flag|
|
|
||||||
define_method(flag + "?") { flags.include? flag }
|
|
||||||
end
|
|
||||||
alias_method :is_64_bit?, :lm?
|
|
||||||
|
|
||||||
def bits
|
|
||||||
is_64_bit? ? 64 : 32
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
require "extend/os/hardware"
|
||||||
|
|
||||||
module ArchitectureListExtension
|
module ArchitectureListExtension
|
||||||
# @private
|
# @private
|
||||||
def fat?
|
def fat?
|
||||||
|
|||||||
@ -1,166 +0,0 @@
|
|||||||
require "os/mac/pathname"
|
|
||||||
|
|
||||||
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",
|
|
||||||
:g5_64 => "-mcpu=970 -arch ppc64"
|
|
||||||
}.freeze
|
|
||||||
def optimization_flags
|
|
||||||
OPTIMIZATION_FLAGS
|
|
||||||
end
|
|
||||||
|
|
||||||
# These methods use info spewed out by sysctl.
|
|
||||||
# Look in <mach/machine.h> for decoding info.
|
|
||||||
def type
|
|
||||||
case sysctl_int("hw.cputype")
|
|
||||||
when 7
|
|
||||||
:intel
|
|
||||||
when 18
|
|
||||||
:ppc
|
|
||||||
else
|
|
||||||
:dunno
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def family
|
|
||||||
if intel?
|
|
||||||
case sysctl_int("hw.cpufamily")
|
|
||||||
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
|
|
||||||
when 0x582ed09c # Broadwell
|
|
||||||
:broadwell
|
|
||||||
when 0x37fc219f # Skylake
|
|
||||||
:skylake
|
|
||||||
else
|
|
||||||
:dunno
|
|
||||||
end
|
|
||||||
elsif ppc?
|
|
||||||
case sysctl_int("hw.cpusubtype")
|
|
||||||
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
|
|
||||||
sysctl_int("machdep.cpu.extmodel")
|
|
||||||
end
|
|
||||||
|
|
||||||
def cores
|
|
||||||
sysctl_int("hw.ncpu")
|
|
||||||
end
|
|
||||||
|
|
||||||
def 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 && !MacOS.prefer_64_bit?
|
|
||||||
[arch_32_bit].extend ArchitectureListExtension
|
|
||||||
else
|
|
||||||
# Amazingly, this order (64, then 32) matters. It shouldn't, but it
|
|
||||||
# does. GCC (some versions? some systems?) can blow up if the other
|
|
||||||
# order is used.
|
|
||||||
# http://superuser.com/questions/740563/gcc-4-8-on-macos-fails-depending-on-arch-order
|
|
||||||
[arch_64_bit, arch_32_bit].extend ArchitectureListExtension
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def features
|
|
||||||
@features ||= sysctl_n(
|
|
||||||
"machdep.cpu.features",
|
|
||||||
"machdep.cpu.extfeatures",
|
|
||||||
"machdep.cpu.leaf7_features"
|
|
||||||
).split(" ").map { |s| s.downcase.to_sym }
|
|
||||||
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
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def sysctl_bool(key)
|
|
||||||
sysctl_int(key) == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
def sysctl_int(key)
|
|
||||||
sysctl_n(key).to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
def sysctl_n(*keys)
|
|
||||||
(@properties ||= {}).fetch(keys) do
|
|
||||||
@properties[keys] = Utils.popen_read("/usr/sbin/sysctl", "-n", *keys)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Loading…
x
Reference in New Issue
Block a user