Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 50 additions & 15 deletions Library/Homebrew/extend/os/linux/hardware/cpu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ module ClassMethods

requires_ancestor { T.class_of(::Hardware::CPU) }

HEX_BASE = 16

sig { returns(T::Hash[Symbol, String]) }
def optimization_flags
@optimization_flags ||= T.let(begin
Expand All @@ -21,23 +23,56 @@ def optimization_flags

sig { returns(Symbol) }
def family
return :arm if arm?
return :ppc if ppc?
return :dunno unless intel?
if arm?
implementer = cpuinfo[/^CPU implementer\s*: (0x\h+)$/i, 1].to_s.hex
cpu_model = cpuinfo[/^CPU part\s*: (0x\h+)$/i, 1].to_s.hex

arm_family(implementer, cpu_model)
elsif intel?
# See https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers
# and https://github.com/llvm/llvm-project/blob/main/llvm/lib/TargetParser/Host.cpp
# and https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures#Roadmap
vendor_id = cpuinfo[/^vendor_id\s*: (.*)/, 1]
cpu_family = cpuinfo[/^cpu family\s*: ([0-9]+)/, 1].to_i
cpu_model = cpuinfo[/^model\s*: ([0-9]+)/, 1].to_i
unknown = :"unknown_0x#{cpu_family.to_s(HEX_BASE)}_0x#{cpu_model.to_s(HEX_BASE)}"
case vendor_id
when "GenuineIntel"
intel_family(cpu_family, cpu_model)
when "AuthenticAMD"
amd_family(cpu_family, cpu_model)
end || unknown
else
:dunno
end
end

sig { params(implementer: Integer, cpu_model: Integer).returns(Symbol) }
def arm_family(implementer, cpu_model)
unknown = :"unknown_#{implementer.to_s(HEX_BASE)}_#{cpu_model.to_s(HEX_BASE)}"
arm_implementer = 0x41
return unknown if implementer != arm_implementer

# See https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers
# See https://en.wikipedia.org/wiki/ARM_architecture_family#Cores
# and https://github.com/llvm/llvm-project/blob/main/llvm/lib/TargetParser/Host.cpp
# and https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures#Roadmap
vendor_id = cpuinfo[/^vendor_id\s*: (.*)/, 1]
cpu_family = cpuinfo[/^cpu family\s*: ([0-9]+)/, 1].to_i
cpu_model = cpuinfo[/^model\s*: ([0-9]+)/, 1].to_i
unknown = :"unknown_0x#{cpu_family.to_s(16)}_0x#{cpu_model.to_s(16)}"
case vendor_id
when "GenuineIntel"
intel_family(cpu_family, cpu_model)
when "AuthenticAMD"
amd_family(cpu_family, cpu_model)
end || unknown
case cpu_model
when 0xc05, 0xc07, 0xc08, 0xc09, 0xc0f, 0xc0e
Comment thread
SMillerDev marked this conversation as resolved.
:armv7_a
when 0xd04, 0xd03, 0xd07, 0xd08, 0xd09, 0xd02
:armv8_0_a
when 0xd05, 0xd0a, 0xd0b, 0xd0d, 0xd41, 0xd44, 0xd0c, 0xd06, 0xd4a, 0xd43
:armv8_2_a
when 0xd40
:armv8_4_a
when 0xd46, 0xd47, 0xd4d, 0xd48, 0xd4e, 0xd49, 0xd4f
:armv9_0_a
when 0xd80, 0xd81, 0xd82, 0xd84, 0xd85, 0xd8e
:armv9_2_a
when 0xd8a, 0xd90, 0xd8b, 0xd8f, 0xd87
:armv9_3_a
else
unknown
end
Comment thread
coderabbitai[bot] marked this conversation as resolved.
end

sig { params(family: Integer, cpu_model: Integer).returns(T.nilable(Symbol)) }
Expand Down
11 changes: 11 additions & 0 deletions Library/Homebrew/test/utils/analytics_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,23 @@

it "returns OS_VERSION, ARM and prefix when HOMEBREW_PREFIX is a custom prefix on arm" do
expect(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once)
expect(described_class.default_package_tags).to have_key(:cpu_family)
expect(described_class.default_package_tags).to have_key(:arch)
expect(described_class.default_package_tags[:arch]).to eq HOMEBREW_PHYSICAL_PROCESSOR
expect(described_class.default_package_tags).to have_key(:prefix)
expect(described_class.default_package_tags[:prefix]).to eq "custom-prefix"
end

it "serialises the Linux ARM CPU family in the package tags", :needs_linux do
allow(Hardware::CPU).to receive_messages(arm?: true, intel?: false)
allow(Hardware::CPU).to receive(:cpuinfo).and_return(
"CPU implementer : 0x41\nCPU part : 0xd08\n",
)
described_class.clear_cache

expect(described_class.default_package_tags[:cpu_family]).to eq "armv8_0_a"
end

it "returns OS_VERSION, Rosetta and prefix when HOMEBREW_PREFIX is a custom prefix on Rosetta", :needs_macos do
expect(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once)
expect(described_class.default_package_tags).to have_key(:prefix)
Expand Down
1 change: 1 addition & 0 deletions Library/Homebrew/utils/analytics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ def default_package_tags
developer: Homebrew::EnvConfig.developer?,
devcmdrun: Homebrew::EnvConfig.devcmdrun?,
arch: HOMEBREW_PHYSICAL_PROCESSOR,
cpu_family: Hardware::CPU.family.to_s,
os: with_wsl_suffix_if_needed(HOMEBREW_SYSTEM),
}
end
Expand Down
Loading