diff --git a/Library/Homebrew/.rubocop_todo.yml b/Library/Homebrew/.rubocop_todo.yml index a2cb90aaec..5b30b296b4 100644 --- a/Library/Homebrew/.rubocop_todo.yml +++ b/Library/Homebrew/.rubocop_todo.yml @@ -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' diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb index 756ca25c85..9bcccedbca 100644 --- a/Library/Homebrew/brew.rb +++ b/Library/Homebrew/brew.rb @@ -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 diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 45fba5500e..4f6d117609 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -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 %> diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 85d8a73ce7..0964ca0be1 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -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 diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb index 46974b7f61..1e636f15ff 100644 --- a/Library/Homebrew/extend/os/mac/diagnostic.rb +++ b/Library/Homebrew/extend/os/mac/diagnostic.rb @@ -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 diff --git a/Library/Homebrew/extend/os/mac/hardware/cpu.rb b/Library/Homebrew/extend/os/mac/hardware/cpu.rb index 2d33360382..746786f98d 100644 --- a/Library/Homebrew/extend/os/mac/hardware/cpu.rb +++ b/Library/Homebrew/extend/os/mac/hardware/cpu.rb @@ -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 diff --git a/Library/Homebrew/extend/os/mac/system_config.rb b/Library/Homebrew/extend/os/mac/system_config.rb index 1f17e08c7f..7faa0f7261 100644 --- a/Library/Homebrew/extend/os/mac/system_config.rb +++ b/Library/Homebrew/extend/os/mac/system_config.rb @@ -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 diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index ce2d502060..aae10e1af1 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -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 diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index af73b4e4df..2cc272a7f5 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -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" diff --git a/Library/Homebrew/hardware.rb b/Library/Homebrew/hardware.rb index 05b5d08ad9..11c78eaf58 100644 --- a/Library/Homebrew/hardware.rb +++ b/Library/Homebrew/hardware.rb @@ -156,7 +156,7 @@ module Hardware "-march=#{arch}" end - def in_rosetta? + def in_rosetta2? false end end diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index f00d3fc402..155a480996 100644 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -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 diff --git a/Library/Homebrew/os/global.rb b/Library/Homebrew/os/global.rb index bbf58536d7..f96f565a4e 100644 --- a/Library/Homebrew/os/global.rb +++ b/Library/Homebrew/os/global.rb @@ -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 diff --git a/Library/Homebrew/os/linux/global.rb b/Library/Homebrew/os/linux/global.rb index 370fa38ed2..891d5a24c7 100644 --- a/Library/Homebrew/os/linux/global.rb +++ b/Library/Homebrew/os/linux/global.rb @@ -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 diff --git a/Library/Homebrew/os/mac/global.rb b/Library/Homebrew/os/mac/global.rb new file mode 100644 index 0000000000..90cc213d62 --- /dev/null +++ b/Library/Homebrew/os/mac/global.rb @@ -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 diff --git a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi index 00bacb7826..24874c0019 100644 --- a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi +++ b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi @@ -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) diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index 5cc7e5e789..4d6a4a7728 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -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, } diff --git a/docs/Installation.md b/docs/Installation.md index 461a603a34..af2951bac6 100644 --- a/docs/Installation.md +++ b/docs/Installation.md @@ -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