diff --git a/Library/Homebrew/compat/hardware.rb b/Library/Homebrew/compat/hardware.rb
index 6667afa588fcf6368bd9153b086f5e538bb07943..5c46a3d3c78f9076b7689f434fe73efa86b017d5 100644
--- a/Library/Homebrew/compat/hardware.rb
+++ b/Library/Homebrew/compat/hardware.rb
@@ -1,4 +1,4 @@
-class Hardware
+module Hardware
   class << self
     # We won't change the name because of backward compatibility.
     # So disable rubocop here.
diff --git a/Library/Homebrew/extend/os/hardware.rb b/Library/Homebrew/extend/os/hardware.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6128072f495a4b83dbf7caad724aa6d78379d712
--- /dev/null
+++ b/Library/Homebrew/extend/os/hardware.rb
@@ -0,0 +1,5 @@
+if OS.mac?
+  require "extend/os/mac/hardware/cpu"
+elsif OS.linux?
+  require "extend/os/linux/hardware/cpu"
+end
diff --git a/Library/Homebrew/extend/os/linux/hardware/cpu.rb b/Library/Homebrew/extend/os/linux/hardware/cpu.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ef25aabfc7c56f970c682933fda840daae0856e5
--- /dev/null
+++ b/Library/Homebrew/extend/os/linux/hardware/cpu.rb
@@ -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
diff --git a/Library/Homebrew/extend/os/mac/hardware/cpu.rb b/Library/Homebrew/extend/os/mac/hardware/cpu.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5f6b4c3a6ec703d05bc8bd7b926d9a4a9e16f675
--- /dev/null
+++ b/Library/Homebrew/extend/os/mac/hardware/cpu.rb
@@ -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
diff --git a/Library/Homebrew/hardware.rb b/Library/Homebrew/hardware.rb
index 7ffd8714bf91cbaf44f9e4c33279d9be530aa4dc..d388967490f816b2eb9a0b82c43f457c421c2d62 100644
--- a/Library/Homebrew/hardware.rb
+++ b/Library/Homebrew/hardware.rb
@@ -1,62 +1,55 @@
 require "os"
 
-class Hardware
-  module CPU
-    extend self
+module Hardware
+  class CPU
     INTEL_32BIT_ARCHS = [:i386].freeze
     INTEL_64BIT_ARCHS = [:x86_64].freeze
     PPC_32BIT_ARCHS   = [:ppc, :ppc7400, :ppc7450, :ppc970].freeze
     PPC_64BIT_ARCHS   = [:ppc64].freeze
 
-    def type
-      :dunno
-    end
+    class << self
+      def type
+        :dunno
+      end
 
-    def family
-      :dunno
-    end
+      def family
+        :dunno
+      end
 
-    def cores
-      1
-    end
+      def cores
+        1
+      end
 
-    def bits
-      64
-    end
+      def bits
+        64
+      end
 
-    def is_32_bit?
-      bits == 32
-    end
+      def is_32_bit?
+        bits == 32
+      end
 
-    def is_64_bit?
-      bits == 64
-    end
+      def is_64_bit?
+        bits == 64
+      end
 
-    def intel?
-      type == :intel
-    end
+      def intel?
+        type == :intel
+      end
 
-    def ppc?
-      type == :ppc
-    end
+      def ppc?
+        type == :ppc
+      end
 
-    def features
-      []
-    end
+      def features
+        []
+      end
 
-    def feature?(name)
-      features.include?(name)
+      def feature?(name)
+        features.include?(name)
+      end
     end
   end
 
-  if OS.mac?
-    require "os/mac/hardware"
-    CPU.extend MacCPUs
-  elsif OS.linux?
-    require "os/linux/hardware"
-    CPU.extend LinuxCPUs
-  end
-
   def self.cores_as_words
     case Hardware::CPU.cores
     when 1 then "single"
@@ -79,3 +72,5 @@ class Hardware
     end
   end
 end
+
+require "extend/os/hardware"
diff --git a/Library/Homebrew/os/linux/hardware.rb b/Library/Homebrew/os/linux/hardware.rb
deleted file mode 100644
index c8d7f4954486583a473d8a458cfc5de7016ea968..0000000000000000000000000000000000000000
--- a/Library/Homebrew/os/linux/hardware.rb
+++ /dev/null
@@ -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
diff --git a/Library/Homebrew/os/mac/architecture_list.rb b/Library/Homebrew/os/mac/architecture_list.rb
index 809a27077c48369a6c433bec76b7b0b82caa0fa3..964cfed0c881eb9448343d9b303e4b125e635372 100644
--- a/Library/Homebrew/os/mac/architecture_list.rb
+++ b/Library/Homebrew/os/mac/architecture_list.rb
@@ -1,3 +1,5 @@
+require "extend/os/hardware"
+
 module ArchitectureListExtension
   # @private
   def fat?
diff --git a/Library/Homebrew/os/mac/hardware.rb b/Library/Homebrew/os/mac/hardware.rb
deleted file mode 100644
index 6b11f6ad509f387e806e6e0527c7395049307f1e..0000000000000000000000000000000000000000
--- a/Library/Homebrew/os/mac/hardware.rb
+++ /dev/null
@@ -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