Merge pull request #9117 from MikeMcQuaid/handle-arm

Handle macOS Homebrew on ARM
This commit is contained in:
Mike McQuaid 2020-11-12 20:14:30 +00:00 committed by GitHub
commit b43c0fed78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 102 additions and 36 deletions

View File

@ -12,6 +12,7 @@ Style/Documentation:
- 'keg_relocate.rb'
- 'os/linux/global.rb'
- 'os/mac/architecture_list.rb'
- 'os/mac/global.rb'
- 'os/mac/keg.rb'
- 'reinstall.rb'
- 'software_spec.rb'

View File

@ -164,7 +164,7 @@ rescue BuildError => e
if e.formula.head? || e.formula.deprecated? || e.formula.disabled?
$stderr.puts <<~EOS
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
end

View File

@ -15,7 +15,9 @@ BOTTLE_ERB = <<-EOS
<% if root_url != "#{HOMEBREW_BOTTLE_DEFAULT_DOMAIN}/bottles" %>
root_url "<%= root_url %>"
<% 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 %>"
<% end %>
<% if cellar.is_a? Symbol %>

View File

@ -112,8 +112,9 @@ module Homebrew
<<~EOS
You will encounter build failures with some formulae.
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
experience while you are running this #{what}.
Discourse, Twitter or any other official channels. You are responsible for
resolving any issues you experience while you are running this
#{what}.
EOS
end

View File

@ -63,6 +63,7 @@ module Homebrew
def supported_configuration_checks
%w[
check_for_unsupported_arch
check_for_unsupported_macos
].freeze
end
@ -90,21 +91,35 @@ module Homebrew
nil
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
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"
if OS::Mac.prerelease?
what = "pre-release version"
# TODO: remove when Big Sur is supported.
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?
who << " (and Apple)"
what = "old version"
else
return
"old version"
end
return if what.blank?
who.freeze
<<~EOS

View File

@ -64,11 +64,11 @@ module Hardware
[arch_64_bit, arch_32_bit].extend ArchitectureListExtension
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
# conflict between what `uname` reports and the underlying `sysctl` flags,
# since the `sysctl` flags don't change behaviour under Rosetta.
def in_rosetta?
# since the `sysctl` flags don't change behaviour under Rosetta 2.
def in_rosetta2?
intel? && physical_cpu_arm64?
end
@ -116,14 +116,14 @@ module Hardware
sysctl_bool("hw.optional.sse4_2")
end
private
# 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?
sysctl_bool("hw.optional.arm64")
end
private
def sysctl_bool(key)
sysctl_int(key) == 1
end

View File

@ -51,6 +51,7 @@ module SystemConfig
f.puts "CLT: #{clt || "N/A"}"
f.puts "Xcode: #{xcode || "N/A"}"
f.puts "XQuartz: #{xquartz}" if xquartz
f.puts "Rosetta 2: #{Hardware::CPU.in_rosetta2?}" if Hardware::CPU.physical_cpu_arm64?
end
end
end

View File

@ -235,12 +235,17 @@ class FormulaInstaller
recursive_formulae = recursive_deps.map(&:to_formula)
recursive_dependencies = []
invalid_arch_dependencies = []
recursive_formulae.each do |dep|
dep_recursive_dependencies = dep.recursive_dependencies.map(&:to_s)
if dep_recursive_dependencies.include?(formula.name)
recursive_dependencies << "#{formula.full_name} depends on #{dep.full_name}"
recursive_dependencies << "#{dep.full_name} depends on #{formula.full_name}"
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
unless recursive_dependencies.empty?
@ -258,6 +263,13 @@ class FormulaInstaller
EOS
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|
dep.to_formula.pinned? && !dep.satisfied?(inherited_options_for(dep))
end

View File

@ -69,7 +69,8 @@ HOMEBREW_USER_AGENT_FAKE_SAFARI =
"(KHTML, like Gecko) Version/10.0.3 Safari/602.4.8"
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 "os/global"

View File

@ -156,7 +156,7 @@ module Hardware
"-march=#{arch}"
end
def in_rosetta?
def in_rosetta2?
false
end
end

View File

@ -14,6 +14,7 @@ module Homebrew
module_function
def perform_preinstall_checks(all_fatal: false, cc: nil)
check_prefix
check_cpu
attempt_directory_creation
check_cc_argv(cc)
@ -28,20 +29,34 @@ module Homebrew
Diagnostic.checks(:build_from_source_checks, fatal: all_fatal)
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
return if Hardware::CPU.intel? && Hardware::CPU.is_64_bit?
message = "Sorry, Homebrew does not support your computer's CPU architecture!"
if Hardware::CPU.arm?
opoo message
return
elsif Hardware::CPU.ppc?
message += <<~EOS
For PowerPC Mac (PPC32/PPC64BE) support, see:
#{Formatter.url("https://github.com/mistydemeo/tigerbrew")}
EOS
end
abort message
# Handled by check_for_unsupported_arch in extend/os/mac/diagnostic.rb
return if Hardware::CPU.arm?
return unless Hardware::CPU.ppc?
odie <<~EOS
Sorry, Homebrew does not support your computer's CPU architecture!
For PowerPC Mac (PPC32/PPC64BE) support, see:
#{Formatter.url("https://github.com/mistydemeo/tigerbrew")}
EOS
end
private_class_method :check_cpu

View File

@ -1,4 +1,8 @@
# typed: strict
# 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

View File

@ -12,6 +12,6 @@ module Homebrew
DEFAULT_PREFIX ||= if Homebrew::EnvConfig.force_homebrew_on_linux?
HOMEBREW_DEFAULT_PREFIX
else
LINUXBREW_DEFAULT_PREFIX
HOMEBREW_LINUX_DEFAULT_PREFIX
end.freeze
end

View 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

View File

@ -13404,8 +13404,10 @@ class Object
HOMEBREW_LIBRARY = ::T.let(nil, ::T.untyped)
HOMEBREW_LIBRARY_PATH = ::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_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_PATCHELF_RB_WRITE = ::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_WWW = ::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)
OFFICIAL_CASK_TAPS = ::T.let(nil, ::T.untyped)
OFFICIAL_CMD_TAPS = ::T.let(nil, ::T.untyped)

View File

@ -186,6 +186,7 @@ class Tab < OpenStruct
"compiler" => DevelopmentTools.default_compiler,
"aliases" => [],
"runtime_dependencies" => nil,
"arch" => nil,
"source" => {
"path" => nil,
"tap" => nil,
@ -345,6 +346,7 @@ class Tab < OpenStruct
"aliases" => aliases,
"runtime_dependencies" => runtime_dependencies,
"source" => source,
"arch" => Hardware::CPU.arch,
"built_on" => built_on,
}

View File

@ -31,10 +31,11 @@ Just extract (or `git clone`) Homebrew wherever you want. Just avoid:
* `/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.
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
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
mkdir homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew