Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
78c3bf9
Don't relocate Apple Silicon bottles for default prefix
samuelarogbonlo Feb 26, 2025
eacb107
Update implementation based on feedback: use env var for gradual roll…
samuelarogbonlo Feb 26, 2025
415582a
Merge branch 'master' into no-relocation-apple-silicon
samuelarogbonlo Feb 28, 2025
0c7cd61
Merge branch 'master' into no-relocation-apple-silicon
samuelarogbonlo Mar 2, 2025
382bc68
Implement binary relocation detection and tab storage
samuelarogbonlo Mar 10, 2025
90a8a37
Merge branch 'master' into no-relocation-apple-silicon
samuelarogbonlo Mar 10, 2025
5b8073c
Fix syntax and style issues
samuelarogbonlo Mar 10, 2025
5c90793
Trigger CI run
samuelarogbonlo Mar 10, 2025
28677ca
Move OS detection to extend/os files
samuelarogbonlo Mar 11, 2025
ee2f160
Remove direct OS.mac? calls
samuelarogbonlo Mar 11, 2025
4606f65
Fix syntax error
samuelarogbonlo Mar 11, 2025
7092e4f
Update formula_installer.rb with minimal changes
samuelarogbonlo Mar 11, 2025
b31e906
Address reviewer feedback: adjust approach to relocation
samuelarogbonlo Mar 11, 2025
585e362
Merge branch 'master' into no-relocation-apple-silicon
samuelarogbonlo Mar 20, 2025
296f9dd
Fix style issues
samuelarogbonlo Mar 20, 2025
9000799
Merge branch 'master' into no-relocation-apple-silicon
samuelarogbonlo Mar 20, 2025
f9f2fd6
Fix style issues
samuelarogbonlo Mar 20, 2025
fd2b54c
Fix parameter name in skip_relocation_for_apple_silicon?
samuelarogbonlo Mar 20, 2025
0ad6185
Fix parameter names and style issues
samuelarogbonlo Mar 20, 2025
9cc4cae
Fix parameter names and style issues
samuelarogbonlo Mar 20, 2025
bf23643
Fix parameter naming consistency for skip_relocation_for_apple_silicon?
samuelarogbonlo Mar 20, 2025
da8cc3c
Fix parameter name in skip_relocation_for_apple_silicon?
samuelarogbonlo Mar 20, 2025
8249c9b
Merge branch 'master' into no-relocation-apple-silicon
samuelarogbonlo Mar 29, 2025
7b8c03a
change how keg_only is handled
samuelarogbonlo Mar 29, 2025
9141156
change how keg is handled
samuelarogbonlo Mar 29, 2025
e019bd5
change how keg is handled
samuelarogbonlo Mar 29, 2025
6ebd623
change how keg is handled
samuelarogbonlo Mar 29, 2025
d22daaf
change how keg is handled
samuelarogbonlo Mar 29, 2025
b6a9754
cleanup for CI jobs
samuelarogbonlo Mar 29, 2025
ff01f23
change how keg is handled
samuelarogbonlo Mar 29, 2025
63c2de0
whitespace cleanup
samuelarogbonlo Mar 29, 2025
2ac554a
whitespace cleanup
samuelarogbonlo Mar 29, 2025
a75a672
whitespace cleanup
samuelarogbonlo Mar 29, 2025
c48fb91
Fix hash alignment in tab.rb
samuelarogbonlo Mar 29, 2025
bb22a2d
whitespace cleanup
samuelarogbonlo Mar 29, 2025
a3bc7d3
whitespace cleanup
samuelarogbonlo Mar 29, 2025
2315426
whitespace cleanup
samuelarogbonlo Mar 29, 2025
e3d7d8d
whitespace cleanup
samuelarogbonlo Mar 29, 2025
056b4c5
whitespace cleanup
samuelarogbonlo Mar 29, 2025
7de3307
whitespace cleanup
samuelarogbonlo Mar 29, 2025
02e1f9b
whitespace cleanup
samuelarogbonlo Mar 29, 2025
9f59138
whitespace cleanup
samuelarogbonlo Mar 29, 2025
c84bc6c
Merge branch 'master' into no-relocation-apple-silicon
samuelarogbonlo Mar 31, 2025
d1ca270
Add --as-dependency and --ask options
samuelarogbonlo Mar 31, 2025
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
2 changes: 1 addition & 1 deletion Library/Homebrew/.ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.7
3.2.2
1 change: 1 addition & 0 deletions Library/Homebrew/cmd/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,4 @@ def run
end
end
end
# Comment
1 change: 1 addition & 0 deletions Library/Homebrew/extend/os/bottles.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
# frozen_string_literal: true

require "extend/os/mac/utils/bottles" if OS.mac?
require "extend/os/linux/utils/bottles" if OS.linux?
18 changes: 18 additions & 0 deletions Library/Homebrew/extend/os/linux/utils/bottles.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# typed: strict
# frozen_string_literal: true

module Utils
module Bottles
class << self
module LinuxOverride
# Linux implementation stays with the default
sig { returns(T::Boolean) }
def on_macos?
false
end
end

prepend LinuxOverride
end
end
end
5 changes: 5 additions & 0 deletions Library/Homebrew/extend/os/mac/formula_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ def fresh_install?(formula)
!::Homebrew::EnvConfig.developer? && !OS::Mac.version.outdated_release? &&
(!installed_as_dependency? || !formula.any_version_installed?)
end

sig { returns(T::Boolean) }
def on_macos?
true
end
end
end
end
Expand Down
26 changes: 26 additions & 0 deletions Library/Homebrew/extend/os/mac/utils/bottles.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,32 @@ def tag(tag = nil)

super
end

# Determines if bottle relocation should be skipped for Apple Silicon with default prefix
sig { params(keg: T.nilable(Keg)).returns(T::Boolean) }
def skip_relocation_for_apple_silicon?(keg = nil)
return false unless Hardware::CPU.arm?
return false if HOMEBREW_PREFIX.to_s != HOMEBREW_MACOS_ARM_DEFAULT_PREFIX

# First check if enabled by env var for gradual rollout
return true if ENV.fetch("HOMEBREW_BOTTLE_SKIP_RELOCATION_ARM64", "false") == "true"

# If not explicitly enabled by env var, check if binaries need relocation
return false unless keg

!binaries_need_relocation?(keg)
end

# Determines if binary files in a keg need relocation
sig { params(keg: Keg).returns(T::Boolean) }
def binaries_need_relocation?(keg)
keg.mach_o_files.any? do |file|
# Check if dylib ID contains paths that need relocation
(file.dylib? && file.dylib_id&.include?(HOMEBREW_MACOS_ARM_DEFAULT_PREFIX)) ||
# Check if linked libraries contain paths that need relocation
file.dynamically_linked_libraries.any? { |lib| lib.include?(HOMEBREW_MACOS_ARM_DEFAULT_PREFIX) }
end
end
end

prepend MacOSOverride
Expand Down
3 changes: 2 additions & 1 deletion Library/Homebrew/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ def initialize(name, path, spec, alias_path: nil, tap: nil, force_bottle: false)
@version_scheme = T.let(self.class.version_scheme || 0, Integer)
@head = T.let(nil, T.nilable(SoftwareSpec))
@stable = T.let(nil, T.nilable(SoftwareSpec))
@keg_only_reason = T.let(nil, T.nilable(KegOnlyReason))

@force_bottle = T.let(force_bottle, T::Boolean)

Expand Down Expand Up @@ -1403,7 +1404,7 @@ def caveats = nil
# @api internal
sig { returns(T::Boolean) }
def keg_only?
return false unless keg_only_reason
return false unless @keg_only_reason

keg_only_reason.applicable?
end
Expand Down
8 changes: 8 additions & 0 deletions Library/Homebrew/formula_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
# Installer for a formula.
class FormulaInstaller
include FormulaCellarChecks
sig { returns(T::Boolean) }
def on_macos?
false
end

ETC_VAR_DIRS = T.let([HOMEBREW_PREFIX/"etc", HOMEBREW_PREFIX/"var"].freeze, T::Array[Pathname])

Expand Down Expand Up @@ -1502,6 +1506,10 @@ def pour
tab.unused_options = []
tab.built_as_bottle = true
tab.poured_from_bottle = true
if Hardware::CPU.arm? && on_macos?
keg_obj = Keg.new(formula.prefix)
tab.skip_relocation_for_apple_silicon = Utils::Bottles.skip_relocation_for_apple_silicon?(keg_obj)
end
tab.loaded_from_api = formula.loaded_from_api?
tab.installed_as_dependency = installed_as_dependency?
tab.installed_on_request = installed_on_request?
Expand Down
8 changes: 7 additions & 1 deletion Library/Homebrew/keg_relocate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ def prepare_relocation_to_placeholders
alias generic_prepare_relocation_to_placeholders prepare_relocation_to_placeholders

def replace_locations_with_placeholders
# Skip relocation for Apple Silicon with default prefix
return [] if Utils::Bottles.skip_relocation_for_apple_silicon?(self)

relocation = prepare_relocation_to_placeholders.freeze
relocate_dynamic_linkage(relocation)
replace_text_in_files(relocation)
Expand All @@ -125,7 +128,10 @@ def prepare_relocation_to_locations
end
alias generic_prepare_relocation_to_locations prepare_relocation_to_locations

def replace_placeholders_with_locations(files, skip_linkage: false)
def replace_placeholders_with_locations(files = nil, skip_linkage: false)
# Skip relocation for Apple Silicon with default prefix
return if Utils::Bottles.skip_relocation_for_apple_silicon?(self)

relocation = prepare_relocation_to_locations.freeze
relocate_dynamic_linkage(relocation) unless skip_linkage
replace_text_in_files(relocation, files:)
Expand Down
58 changes: 30 additions & 28 deletions Library/Homebrew/tab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,20 @@ def self.from_file_content(content, path)

def self.empty
attributes = {
"homebrew_version" => HOMEBREW_VERSION,
"installed_as_dependency" => false,
"installed_on_request" => false,
"loaded_from_api" => false,
"time" => nil,
"runtime_dependencies" => nil,
"arch" => nil,
"source" => {
"homebrew_version" => HOMEBREW_VERSION,
"installed_as_dependency" => false,
"installed_on_request" => false,
"loaded_from_api" => false,
"time" => nil,
"runtime_dependencies" => nil,
"arch" => nil,
"source" => {
"path" => nil,
"tap" => nil,
"tap_git_head" => nil,
},
"built_on" => DevelopmentTools.build_system_info,
"built_on" => DevelopmentTools.build_system_info,
"skip_relocation_for_apple_silicon" => false,
}

new(attributes)
Expand Down Expand Up @@ -140,7 +141,7 @@ class Tab < AbstractTab
# @api internal
attr_accessor :poured_from_bottle

attr_accessor :built_as_bottle, :changed_files, :stdlib, :aliases
attr_accessor :built_as_bottle, :changed_files, :stdlib, :aliases, :skip_relocation_for_apple_silicon
attr_writer :used_options, :unused_options, :compiler, :source_modified_time
attr_reader :tapped_from

Expand Down Expand Up @@ -399,24 +400,25 @@ def source_modified_time

def to_json(options = nil)
attributes = {
"homebrew_version" => homebrew_version,
"used_options" => used_options.as_flags,
"unused_options" => unused_options.as_flags,
"built_as_bottle" => built_as_bottle,
"poured_from_bottle" => poured_from_bottle,
"loaded_from_api" => loaded_from_api,
"installed_as_dependency" => installed_as_dependency,
"installed_on_request" => installed_on_request,
"changed_files" => changed_files&.map(&:to_s),
"time" => time,
"source_modified_time" => source_modified_time.to_i,
"stdlib" => stdlib&.to_s,
"compiler" => compiler&.to_s,
"aliases" => aliases,
"runtime_dependencies" => runtime_dependencies,
"source" => source,
"arch" => arch,
"built_on" => built_on,
"homebrew_version" => homebrew_version,
"used_options" => used_options.as_flags,
"unused_options" => unused_options.as_flags,
"built_as_bottle" => built_as_bottle,
"poured_from_bottle" => poured_from_bottle,
"skip_relocation_for_apple_silicon" => skip_relocation_for_apple_silicon,
"loaded_from_api" => loaded_from_api,
"installed_as_dependency" => installed_as_dependency,
"installed_on_request" => installed_on_request,
"changed_files" => changed_files&.map(&:to_s),
"time" => time,
"source_modified_time" => source_modified_time.to_i,
"stdlib" => stdlib&.to_s,
"compiler" => compiler&.to_s,
"aliases" => aliases,
"runtime_dependencies" => runtime_dependencies,
"source" => source,
"arch" => arch,
"built_on" => built_on,
}
attributes.delete("stdlib") if attributes["stdlib"].blank?

Expand Down
98 changes: 98 additions & 0 deletions Library/Homebrew/test/utils/bottles/bottles_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,102 @@ class #{Formulary.class_s(formula_name)} < Formula
end
end
end

describe "#skip_relocation_for_apple_silicon?" do
let(:keg) { instance_double(Keg) }

before do
allow(keg).to receive(:mach_o_files).and_return([])
end

it "returns true for Apple Silicon with default prefix when enabled by env var" do
allow(Hardware::CPU).to receive(:arm?).and_return(true)
allow(OS).to receive(:mac?).and_return(true)
allow(HOMEBREW_PREFIX).to receive(:to_s).and_return(HOMEBREW_MACOS_ARM_DEFAULT_PREFIX)
allow(ENV).to receive(:fetch).with("HOMEBREW_BOTTLE_SKIP_RELOCATION_ARM64", "false").and_return("true")

expect(described_class.skip_relocation_for_apple_silicon?).to be true
end

it "returns true for Apple Silicon with default prefix when no binaries need relocation" do
allow(Hardware::CPU).to receive(:arm?).and_return(true)
allow(OS).to receive(:mac?).and_return(true)
allow(HOMEBREW_PREFIX).to receive(:to_s).and_return(HOMEBREW_MACOS_ARM_DEFAULT_PREFIX)
allow(ENV).to receive(:fetch).with("HOMEBREW_BOTTLE_SKIP_RELOCATION_ARM64", "false").and_return("false")

expect(described_class.skip_relocation_for_apple_silicon?(keg)).to be true
end

it "returns false for Apple Silicon with default prefix when binaries need relocation" do
mach_o_file = instance_double(MachO::MachOFile)
allow(keg).to receive(:mach_o_files).and_return([mach_o_file])
allow(mach_o_file).to receive_messages(
dylib?: true,
dylib_id: "/usr/local/lib/example.dylib",
)

allow(Hardware::CPU).to receive(:arm?).and_return(true)
allow(OS).to receive(:mac?).and_return(true)
allow(HOMEBREW_PREFIX).to receive(:to_s).and_return(HOMEBREW_MACOS_ARM_DEFAULT_PREFIX)
allow(ENV).to receive(:fetch).with("HOMEBREW_BOTTLE_SKIP_RELOCATION_ARM64", "false").and_return("false")

expect(described_class.skip_relocation_for_apple_silicon?(keg)).to be false
end

it "returns false for Intel Mac" do
allow(Hardware::CPU).to receive(:arm?).and_return(false)
allow(OS).to receive(:mac?).and_return(true)

expect(described_class.skip_relocation_for_apple_silicon?).to be false
expect(described_class.skip_relocation_for_apple_silicon?(keg)).to be false
end

it "returns false for custom prefix on Apple Silicon" do
allow(Hardware::CPU).to receive(:arm?).and_return(true)
allow(OS).to receive(:mac?).and_return(true)
allow(HOMEBREW_PREFIX).to receive(:to_s).and_return("/custom/path")

expect(described_class.skip_relocation_for_apple_silicon?).to be false
expect(described_class.skip_relocation_for_apple_silicon?(keg)).to be false
end
end

describe "#binaries_need_relocation?" do
let(:keg) { instance_double(Keg) }
let(:mach_o_file) { instance_double(MachO::MachOFile) }

it "returns true when dylib has /usr/local path" do
allow(OS).to receive(:mac?).and_return(true)
allow(keg).to receive(:mach_o_files).and_return([mach_o_file])
allow(mach_o_file).to receive_messages(
dylib?: true,
dylib_id: "/usr/local/lib/example.dylib",
)
allow(mach_o_file).to receive(:dynamically_linked_libraries).and_return([])

expect(described_class.binaries_need_relocation?(keg)).to be true
end

it "returns true when linked libraries have /usr/local path" do
allow(OS).to receive(:mac?).and_return(true)
allow(keg).to receive(:mach_o_files).and_return([mach_o_file])
allow(mach_o_file).to receive_messages(
dylib?: true,
dylib_id: "/usr/local/lib/example.dylib",
)

expect(described_class.binaries_need_relocation?(keg)).to be true
end

it "returns false when no paths need relocation" do
allow(OS).to receive(:mac?).and_return(true)
allow(keg).to receive(:mach_o_files).and_return([mach_o_file])
allow(mach_o_file).to receive_messages(
dylib?: true,
dylib_id: "/usr/local/lib/example.dylib",
)

expect(described_class.binaries_need_relocation?(keg)).to be false
end
end
end
15 changes: 15 additions & 0 deletions Library/Homebrew/utils/bottles.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,20 @@ def load_tab(formula)
end
end

# Determines if bottle relocation should be skipped for Apple Silicon with default prefix
sig { params(_keg: T.nilable(Keg)).returns(T::Boolean) }
def skip_relocation_for_apple_silicon?(_keg = nil)
# This is a stub that will be overriden in platform-specific files
false
end

# Determines if binary files in a keg need relocation
sig { params(_keg: Keg).returns(T::Boolean) }
def binaries_need_relocation?(_keg)
# This is a stub that will be overriden in platform-specific files
false
end

private

def bottle_file_list(bottle_file)
Expand Down Expand Up @@ -350,3 +364,4 @@ def find_matching_tag(tag, no_older_versions: false)
end

require "extend/os/bottles"
# Trigger CI run
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
require 'bindata/warnings'

# = BinData
#
#
# A declarative way to read and write structured binary data.
#
#
# A full reference manual is available online at
# https://github.com/dmendel/bindata/wiki
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module BinData
# Error raised when unexpected results occur when reading data from IO.
class ValidityError < StandardError; end

# All methods provided by the framework are to be implemented or overridden
# All methods provided by the framework are to be implemented or overridden
# by subclasses of BinData::Base.
module Framework
# Initializes the state of the object. All instance variables that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Collection


# @!macro priority_queue
#
#
# @!visibility private
# @!macro internal_implementation_note
class JavaNonConcurrentPriorityQueue
Expand Down
Loading
Loading