Merge pull request #9117 from MikeMcQuaid/handle-arm
Handle macOS Homebrew on ARM
This commit is contained in:
commit
b43c0fed78
@ -12,6 +12,7 @@ Style/Documentation:
|
|||||||
- 'keg_relocate.rb'
|
- 'keg_relocate.rb'
|
||||||
- 'os/linux/global.rb'
|
- 'os/linux/global.rb'
|
||||||
- 'os/mac/architecture_list.rb'
|
- 'os/mac/architecture_list.rb'
|
||||||
|
- 'os/mac/global.rb'
|
||||||
- 'os/mac/keg.rb'
|
- 'os/mac/keg.rb'
|
||||||
- 'reinstall.rb'
|
- 'reinstall.rb'
|
||||||
- 'software_spec.rb'
|
- 'software_spec.rb'
|
||||||
|
@ -164,7 +164,7 @@ rescue BuildError => e
|
|||||||
if e.formula.head? || e.formula.deprecated? || e.formula.disabled?
|
if e.formula.head? || e.formula.deprecated? || e.formula.disabled?
|
||||||
$stderr.puts <<~EOS
|
$stderr.puts <<~EOS
|
||||||
Please create pull requests instead of asking for help on Homebrew's GitHub,
|
Please create pull requests instead of asking for help on Homebrew's GitHub,
|
||||||
Discourse, Twitter or IRC.
|
Discourse, Twitter or any other official channels.
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -15,7 +15,9 @@ BOTTLE_ERB = <<-EOS
|
|||||||
<% if root_url != "#{HOMEBREW_BOTTLE_DEFAULT_DOMAIN}/bottles" %>
|
<% if root_url != "#{HOMEBREW_BOTTLE_DEFAULT_DOMAIN}/bottles" %>
|
||||||
root_url "<%= root_url %>"
|
root_url "<%= root_url %>"
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if ![HOMEBREW_DEFAULT_PREFIX, LINUXBREW_DEFAULT_PREFIX].include?(prefix) %>
|
<% if ![HOMEBREW_DEFAULT_PREFIX,
|
||||||
|
HOMEBREW_MACOS_ARM_DEFAULT_PREFIX,
|
||||||
|
HOMEBREW_LINUX_DEFAULT_PREFIX].include?(prefix) %>
|
||||||
prefix "<%= prefix %>"
|
prefix "<%= prefix %>"
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if cellar.is_a? Symbol %>
|
<% if cellar.is_a? Symbol %>
|
||||||
|
@ -112,8 +112,9 @@ module Homebrew
|
|||||||
<<~EOS
|
<<~EOS
|
||||||
You will encounter build failures with some formulae.
|
You will encounter build failures with some formulae.
|
||||||
Please create pull requests instead of asking for help on Homebrew's GitHub,
|
Please create pull requests instead of asking for help on Homebrew's GitHub,
|
||||||
Discourse, Twitter or IRC. You are responsible for resolving any issues you
|
Discourse, Twitter or any other official channels. You are responsible for
|
||||||
experience while you are running this #{what}.
|
resolving any issues you experience while you are running this
|
||||||
|
#{what}.
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ module Homebrew
|
|||||||
|
|
||||||
def supported_configuration_checks
|
def supported_configuration_checks
|
||||||
%w[
|
%w[
|
||||||
|
check_for_unsupported_arch
|
||||||
check_for_unsupported_macos
|
check_for_unsupported_macos
|
||||||
].freeze
|
].freeze
|
||||||
end
|
end
|
||||||
@ -90,21 +91,35 @@ module Homebrew
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_for_unsupported_arch
|
||||||
|
return if Homebrew::EnvConfig.developer?
|
||||||
|
return unless Hardware::CPU.arm?
|
||||||
|
|
||||||
|
<<~EOS
|
||||||
|
You are running macOS on a #{Hardware::CPU.arch} CPU architecture.
|
||||||
|
We do not provide support for this (yet).
|
||||||
|
Reinstall Homebrew under Rosetta 2 until we support it.
|
||||||
|
#{please_create_pull_requests}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
def check_for_unsupported_macos
|
def check_for_unsupported_macos
|
||||||
return if Homebrew::EnvConfig.developer?
|
return if Homebrew::EnvConfig.developer?
|
||||||
|
|
||||||
# TODO: remove when Big Sur is released.
|
|
||||||
return if MacOS.version == :big_sur && ENV["HOMEBREW_GITHUB_ACTIONS_BIG_SUR_TESTING"]
|
|
||||||
|
|
||||||
who = +"We"
|
who = +"We"
|
||||||
if OS::Mac.prerelease?
|
# TODO: remove when Big Sur is supported.
|
||||||
what = "pre-release version"
|
what = if MacOS.version == :big_sur
|
||||||
|
return if ENV["HOMEBREW_GITHUB_ACTIONS_BIG_SUR_TESTING"]
|
||||||
|
|
||||||
|
"released but not yet supported version"
|
||||||
|
elsif OS::Mac.prerelease?
|
||||||
|
"pre-release version"
|
||||||
elsif OS::Mac.outdated_release?
|
elsif OS::Mac.outdated_release?
|
||||||
who << " (and Apple)"
|
who << " (and Apple)"
|
||||||
what = "old version"
|
"old version"
|
||||||
else
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
return if what.blank?
|
||||||
|
|
||||||
who.freeze
|
who.freeze
|
||||||
|
|
||||||
<<~EOS
|
<<~EOS
|
||||||
|
@ -64,11 +64,11 @@ module Hardware
|
|||||||
[arch_64_bit, arch_32_bit].extend ArchitectureListExtension
|
[arch_64_bit, arch_32_bit].extend ArchitectureListExtension
|
||||||
end
|
end
|
||||||
|
|
||||||
# True when running under an Intel-based shell via Rosetta on an
|
# True when running under an Intel-based shell via Rosetta 2 on an
|
||||||
# Apple Silicon Mac. This can be detected via seeing if there's a
|
# Apple Silicon Mac. This can be detected via seeing if there's a
|
||||||
# conflict between what `uname` reports and the underlying `sysctl` flags,
|
# conflict between what `uname` reports and the underlying `sysctl` flags,
|
||||||
# since the `sysctl` flags don't change behaviour under Rosetta.
|
# since the `sysctl` flags don't change behaviour under Rosetta 2.
|
||||||
def in_rosetta?
|
def in_rosetta2?
|
||||||
intel? && physical_cpu_arm64?
|
intel? && physical_cpu_arm64?
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -116,14 +116,14 @@ module Hardware
|
|||||||
sysctl_bool("hw.optional.sse4_2")
|
sysctl_bool("hw.optional.sse4_2")
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# Note: this is more reliable than checking uname.
|
# Note: this is more reliable than checking uname.
|
||||||
# `sysctl` returns the right answer even when running in Rosetta.
|
# `sysctl` returns the right answer even when running in Rosetta 2.
|
||||||
def physical_cpu_arm64?
|
def physical_cpu_arm64?
|
||||||
sysctl_bool("hw.optional.arm64")
|
sysctl_bool("hw.optional.arm64")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
def sysctl_bool(key)
|
def sysctl_bool(key)
|
||||||
sysctl_int(key) == 1
|
sysctl_int(key) == 1
|
||||||
end
|
end
|
||||||
|
@ -51,6 +51,7 @@ module SystemConfig
|
|||||||
f.puts "CLT: #{clt || "N/A"}"
|
f.puts "CLT: #{clt || "N/A"}"
|
||||||
f.puts "Xcode: #{xcode || "N/A"}"
|
f.puts "Xcode: #{xcode || "N/A"}"
|
||||||
f.puts "XQuartz: #{xquartz}" if xquartz
|
f.puts "XQuartz: #{xquartz}" if xquartz
|
||||||
|
f.puts "Rosetta 2: #{Hardware::CPU.in_rosetta2?}" if Hardware::CPU.physical_cpu_arm64?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -235,12 +235,17 @@ class FormulaInstaller
|
|||||||
recursive_formulae = recursive_deps.map(&:to_formula)
|
recursive_formulae = recursive_deps.map(&:to_formula)
|
||||||
|
|
||||||
recursive_dependencies = []
|
recursive_dependencies = []
|
||||||
|
invalid_arch_dependencies = []
|
||||||
recursive_formulae.each do |dep|
|
recursive_formulae.each do |dep|
|
||||||
dep_recursive_dependencies = dep.recursive_dependencies.map(&:to_s)
|
dep_recursive_dependencies = dep.recursive_dependencies.map(&:to_s)
|
||||||
if dep_recursive_dependencies.include?(formula.name)
|
if dep_recursive_dependencies.include?(formula.name)
|
||||||
recursive_dependencies << "#{formula.full_name} depends on #{dep.full_name}"
|
recursive_dependencies << "#{formula.full_name} depends on #{dep.full_name}"
|
||||||
recursive_dependencies << "#{dep.full_name} depends on #{formula.full_name}"
|
recursive_dependencies << "#{dep.full_name} depends on #{formula.full_name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (tab = Tab.for_formula(dep)) && tab.arch.present? && tab.arch.to_s != Hardware::CPU.arch.to_s
|
||||||
|
invalid_arch_dependencies << "#{dep} was built for #{tab.arch}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unless recursive_dependencies.empty?
|
unless recursive_dependencies.empty?
|
||||||
@ -258,6 +263,13 @@ class FormulaInstaller
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless invalid_arch_dependencies.empty?
|
||||||
|
raise CannotInstallFormulaError, <<~EOS
|
||||||
|
#{formula.full_name} dependencies not built for the #{Hardware::CPU.arch} CPU architecture:
|
||||||
|
#{invalid_arch_dependencies.join("\n ")}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
pinned_unsatisfied_deps = recursive_deps.select do |dep|
|
pinned_unsatisfied_deps = recursive_deps.select do |dep|
|
||||||
dep.to_formula.pinned? && !dep.satisfied?(inherited_options_for(dep))
|
dep.to_formula.pinned? && !dep.satisfied?(inherited_options_for(dep))
|
||||||
end
|
end
|
||||||
|
@ -69,7 +69,8 @@ HOMEBREW_USER_AGENT_FAKE_SAFARI =
|
|||||||
"(KHTML, like Gecko) Version/10.0.3 Safari/602.4.8"
|
"(KHTML, like Gecko) Version/10.0.3 Safari/602.4.8"
|
||||||
|
|
||||||
HOMEBREW_DEFAULT_PREFIX = "/usr/local"
|
HOMEBREW_DEFAULT_PREFIX = "/usr/local"
|
||||||
LINUXBREW_DEFAULT_PREFIX = "/home/linuxbrew/.linuxbrew"
|
HOMEBREW_MACOS_ARM_DEFAULT_PREFIX = "/opt/homebrew"
|
||||||
|
HOMEBREW_LINUX_DEFAULT_PREFIX = "/home/linuxbrew/.linuxbrew"
|
||||||
|
|
||||||
require "fileutils"
|
require "fileutils"
|
||||||
require "os/global"
|
require "os/global"
|
||||||
|
@ -156,7 +156,7 @@ module Hardware
|
|||||||
"-march=#{arch}"
|
"-march=#{arch}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def in_rosetta?
|
def in_rosetta2?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -14,6 +14,7 @@ module Homebrew
|
|||||||
module_function
|
module_function
|
||||||
|
|
||||||
def perform_preinstall_checks(all_fatal: false, cc: nil)
|
def perform_preinstall_checks(all_fatal: false, cc: nil)
|
||||||
|
check_prefix
|
||||||
check_cpu
|
check_cpu
|
||||||
attempt_directory_creation
|
attempt_directory_creation
|
||||||
check_cc_argv(cc)
|
check_cc_argv(cc)
|
||||||
@ -28,21 +29,35 @@ module Homebrew
|
|||||||
Diagnostic.checks(:build_from_source_checks, fatal: all_fatal)
|
Diagnostic.checks(:build_from_source_checks, fatal: all_fatal)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_prefix
|
||||||
|
if Hardware::CPU.intel? && HOMEBREW_PREFIX.to_s == HOMEBREW_MACOS_ARM_DEFAULT_PREFIX
|
||||||
|
odie "Cannot install in Homebrew on Intel processor in ARM default prefix (#{HOMEBREW_PREFIX})!"
|
||||||
|
elsif Hardware::CPU.arm? && HOMEBREW_PREFIX.to_s == HOMEBREW_DEFAULT_PREFIX
|
||||||
|
odie <<~EOS
|
||||||
|
Cannot install in Homebrew on ARM processor in Intel default prefix (#{HOMEBREW_PREFIX})!
|
||||||
|
Please create a new installation in #{HOMEBREW_MACOS_ARM_DEFAULT_PREFIX} using one of the
|
||||||
|
"Alternative Installs" from:
|
||||||
|
#{Formatter.url("https://docs.brew.sh/Installation")}
|
||||||
|
You can migrate your previously installed formula list with:
|
||||||
|
brew bundle dump
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def check_cpu
|
def check_cpu
|
||||||
return if Hardware::CPU.intel? && Hardware::CPU.is_64_bit?
|
return if Hardware::CPU.intel? && Hardware::CPU.is_64_bit?
|
||||||
|
|
||||||
message = "Sorry, Homebrew does not support your computer's CPU architecture!"
|
# Handled by check_for_unsupported_arch in extend/os/mac/diagnostic.rb
|
||||||
if Hardware::CPU.arm?
|
return if Hardware::CPU.arm?
|
||||||
opoo message
|
|
||||||
return
|
return unless Hardware::CPU.ppc?
|
||||||
elsif Hardware::CPU.ppc?
|
|
||||||
message += <<~EOS
|
odie <<~EOS
|
||||||
|
Sorry, Homebrew does not support your computer's CPU architecture!
|
||||||
For PowerPC Mac (PPC32/PPC64BE) support, see:
|
For PowerPC Mac (PPC32/PPC64BE) support, see:
|
||||||
#{Formatter.url("https://github.com/mistydemeo/tigerbrew")}
|
#{Formatter.url("https://github.com/mistydemeo/tigerbrew")}
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
abort message
|
|
||||||
end
|
|
||||||
private_class_method :check_cpu
|
private_class_method :check_cpu
|
||||||
|
|
||||||
def attempt_directory_creation
|
def attempt_directory_creation
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "os/linux/global" if OS.linux?
|
if OS.mac?
|
||||||
|
require "os/mac/global"
|
||||||
|
elsif OS.linux?
|
||||||
|
require "os/linux/global"
|
||||||
|
end
|
||||||
|
@ -12,6 +12,6 @@ module Homebrew
|
|||||||
DEFAULT_PREFIX ||= if Homebrew::EnvConfig.force_homebrew_on_linux?
|
DEFAULT_PREFIX ||= if Homebrew::EnvConfig.force_homebrew_on_linux?
|
||||||
HOMEBREW_DEFAULT_PREFIX
|
HOMEBREW_DEFAULT_PREFIX
|
||||||
else
|
else
|
||||||
LINUXBREW_DEFAULT_PREFIX
|
HOMEBREW_LINUX_DEFAULT_PREFIX
|
||||||
end.freeze
|
end.freeze
|
||||||
end
|
end
|
||||||
|
10
Library/Homebrew/os/mac/global.rb
Normal file
10
Library/Homebrew/os/mac/global.rb
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# typed: false
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Homebrew
|
||||||
|
DEFAULT_PREFIX ||= if Hardware::CPU.arm?
|
||||||
|
HOMEBREW_MACOS_ARM_DEFAULT_PREFIX
|
||||||
|
else
|
||||||
|
HOMEBREW_DEFAULT_PREFIX
|
||||||
|
end.freeze
|
||||||
|
end
|
@ -13404,8 +13404,10 @@ class Object
|
|||||||
HOMEBREW_LIBRARY = ::T.let(nil, ::T.untyped)
|
HOMEBREW_LIBRARY = ::T.let(nil, ::T.untyped)
|
||||||
HOMEBREW_LIBRARY_PATH = ::T.let(nil, ::T.untyped)
|
HOMEBREW_LIBRARY_PATH = ::T.let(nil, ::T.untyped)
|
||||||
HOMEBREW_LINKED_KEGS = ::T.let(nil, ::T.untyped)
|
HOMEBREW_LINKED_KEGS = ::T.let(nil, ::T.untyped)
|
||||||
|
HOMEBREW_LINUX_DEFAULT_PREFIX = ::T.let(nil, ::T.untyped)
|
||||||
HOMEBREW_LOCKS = ::T.let(nil, ::T.untyped)
|
HOMEBREW_LOCKS = ::T.let(nil, ::T.untyped)
|
||||||
HOMEBREW_LOGS = ::T.let(nil, ::T.untyped)
|
HOMEBREW_LOGS = ::T.let(nil, ::T.untyped)
|
||||||
|
HOMEBREW_MACOS_ARM_DEFAULT_PREFIX = ::T.let(nil, ::T.untyped)
|
||||||
HOMEBREW_OFFICIAL_REPO_PREFIXES_REGEX = ::T.let(nil, ::T.untyped)
|
HOMEBREW_OFFICIAL_REPO_PREFIXES_REGEX = ::T.let(nil, ::T.untyped)
|
||||||
HOMEBREW_PATCHELF_RB_WRITE = ::T.let(nil, ::T.untyped)
|
HOMEBREW_PATCHELF_RB_WRITE = ::T.let(nil, ::T.untyped)
|
||||||
HOMEBREW_PINNED_KEGS = ::T.let(nil, ::T.untyped)
|
HOMEBREW_PINNED_KEGS = ::T.let(nil, ::T.untyped)
|
||||||
@ -13428,7 +13430,6 @@ class Object
|
|||||||
HOMEBREW_VERSION = ::T.let(nil, ::T.untyped)
|
HOMEBREW_VERSION = ::T.let(nil, ::T.untyped)
|
||||||
HOMEBREW_WWW = ::T.let(nil, ::T.untyped)
|
HOMEBREW_WWW = ::T.let(nil, ::T.untyped)
|
||||||
HOMEPAGE_URL = ::T.let(nil, ::T.untyped)
|
HOMEPAGE_URL = ::T.let(nil, ::T.untyped)
|
||||||
LINUXBREW_DEFAULT_PREFIX = ::T.let(nil, ::T.untyped)
|
|
||||||
MAXIMUM_STRING_MATCHES = ::T.let(nil, ::T.untyped)
|
MAXIMUM_STRING_MATCHES = ::T.let(nil, ::T.untyped)
|
||||||
OFFICIAL_CASK_TAPS = ::T.let(nil, ::T.untyped)
|
OFFICIAL_CASK_TAPS = ::T.let(nil, ::T.untyped)
|
||||||
OFFICIAL_CMD_TAPS = ::T.let(nil, ::T.untyped)
|
OFFICIAL_CMD_TAPS = ::T.let(nil, ::T.untyped)
|
||||||
|
@ -186,6 +186,7 @@ class Tab < OpenStruct
|
|||||||
"compiler" => DevelopmentTools.default_compiler,
|
"compiler" => DevelopmentTools.default_compiler,
|
||||||
"aliases" => [],
|
"aliases" => [],
|
||||||
"runtime_dependencies" => nil,
|
"runtime_dependencies" => nil,
|
||||||
|
"arch" => nil,
|
||||||
"source" => {
|
"source" => {
|
||||||
"path" => nil,
|
"path" => nil,
|
||||||
"tap" => nil,
|
"tap" => nil,
|
||||||
@ -345,6 +346,7 @@ class Tab < OpenStruct
|
|||||||
"aliases" => aliases,
|
"aliases" => aliases,
|
||||||
"runtime_dependencies" => runtime_dependencies,
|
"runtime_dependencies" => runtime_dependencies,
|
||||||
"source" => source,
|
"source" => source,
|
||||||
|
"arch" => Hardware::CPU.arch,
|
||||||
"built_on" => built_on,
|
"built_on" => built_on,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,10 +31,11 @@ Just extract (or `git clone`) Homebrew wherever you want. Just avoid:
|
|||||||
* `/tmp` subdirectories because Homebrew gets upset.
|
* `/tmp` subdirectories because Homebrew gets upset.
|
||||||
* `/sw` and `/opt/local` because build scripts get confused when Homebrew is there instead of Fink or MacPorts, respectively.
|
* `/sw` and `/opt/local` because build scripts get confused when Homebrew is there instead of Fink or MacPorts, respectively.
|
||||||
|
|
||||||
However do yourself a favour and install to `/usr/local`. Some things may
|
However do yourself a favour and install to `/usr/local` on macOS Intel, `/opt/homebrew` on macOS ARM
|
||||||
|
and `.home/linuxbrew/.linuxbrew` on Linux. Some things may
|
||||||
not build when installed elsewhere. One of the reasons Homebrew just
|
not build when installed elsewhere. One of the reasons Homebrew just
|
||||||
works relative to the competition is **because** we recommend installing
|
works relative to the competition is **because** we recommend installing
|
||||||
to `/usr/local`. *Pick another prefix at your peril!*
|
here. *Pick another prefix at your peril!*
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
|
mkdir homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
|
||||||
|
Loading…
x
Reference in New Issue
Block a user