Module: OS::Mac Private

Defined in:
os/mac.rb,
os/linux.rb,
cask/macos.rb,
os/mac/sdk.rb,
os/mac/xcode.rb,
macos_version.rb

This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.

Defined Under Namespace

Modules: CLT, Xcode Classes: CLTSDKLocator, SDK, XcodeSDKLocator

Constant Summary collapse

Version =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

TODO:

Replace ::Version with Version when this is removed.

LazyObject.new do # rubocop:disable Style/MutableConstant
  odisabled "`OS::Mac::Version`", "`MacOSVersion`"
  MacOSVersion
end

Class Method Summary collapse

Class Method Details

.active_developer_dirString

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



91
92
93
# File 'os/mac.rb', line 91

def self.active_developer_dir
  @active_developer_dir ||= Utils.popen_read("/usr/bin/xcode-select", "-print-path").strip
end

.app_with_bundle_id(*ids) ⇒ Pathname?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



201
202
203
204
205
206
# File 'os/mac.rb', line 201

def self.app_with_bundle_id(*ids)
  path = mdfind(*ids)
         .reject { |p| p.include?("/Backups.backupdb/") }
         .first
  Pathname.new(path) if path.present?
end

.full_versionMacOSVersion

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This can be compared to numerics, strings, or symbols using the standard Ruby Comparable methods.

Returns:



38
39
40
41
42
43
44
45
# File 'os/mac.rb', line 38

def self.full_version
  odeprecated "`MacOS.full_version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
  @full_version ||= if (fake_macos = ENV.fetch("HOMEBREW_FAKE_MACOS", nil)) # for Portable Ruby building
    MacOSVersion.new(fake_macos)
  else
    MacOSVersion.new(VERSION)
  end
end

.full_version=(version) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method returns an undefined value.

Parameters:



48
49
50
51
# File 'os/mac.rb', line 48

def self.full_version=(version)
  @full_version = MacOSVersion.new(version.chomp)
  @version = nil
end

.languageObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



85
86
87
88
# File 'os/mac.rb', line 85

def self.language
  odeprecated "`MacOS.language` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
  languages.first
end

.languagesObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'os/mac.rb', line 71

def self.languages
  odeprecated "`MacOS.languages` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
  return @languages if @languages

  os_langs = Utils.popen_read("defaults", "read", "-g", "AppleLanguages")
  if os_langs.blank?
    # User settings don't exist so check the system-wide one.
    os_langs = Utils.popen_read("defaults", "read", "/Library/Preferences/.GlobalPreferences", "AppleLanguages")
  end
  os_langs = os_langs.scan(/[^ \n"(),]+/)

  @languages = os_langs
end

.latest_sdk_version::Version

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



54
55
56
57
58
# File 'os/mac.rb', line 54

def self.latest_sdk_version
  # TODO: bump version when new Xcode macOS SDK is released
  # NOTE: We only track the major version of the SDK.
  ::Version.new("13")
end

.macports_or_finkObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

See these issues for some history:



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'os/mac.rb', line 171

def self.macports_or_fink
  paths = []

  # First look in the path because MacPorts is relocatable and Fink
  # may become relocatable in the future.
  %w[port fink].each do |ponk|
    path = which(ponk)
    paths << path unless path.nil?
  end

  # Look in the standard locations, because even if port or fink are
  # not in the path they can still break builds if the build scripts
  # have these paths baked in.
  %w[/sw/bin/fink /opt/local/bin/port].each do |ponk|
    path = Pathname.new(ponk)
    paths << path if path.exist?
  end

  # Finally, some users make their MacPorts or Fink directories
  # read-only in order to try out Homebrew, but this doesn't work as
  # some build scripts error out when trying to read from these now
  # unreadable paths.
  %w[/sw /opt/local].map { |p| Pathname.new(p) }.each do |path|
    paths << path if path.exist? && !path.readable?
  end

  paths.uniq
end

.mdfind(*ids) ⇒ Array<String>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



209
210
211
212
213
# File 'os/mac.rb', line 209

def self.mdfind(*ids)
  (@mdfind ||= {}).fetch(ids) do
    @mdfind[ids] = Utils.popen_read("/usr/bin/mdfind", mdfind_query(*ids)).split("\n")
  end
end

.mdfind_query(*ids) ⇒ String

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:



222
223
224
# File 'os/mac.rb', line 222

def self.mdfind_query(*ids)
  ids.map! { |id| "kMDItemCFBundleIdentifier == #{id}" }.join(" || ")
end

.pkgutil_info(id) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



215
216
217
218
219
# File 'os/mac.rb', line 215

def self.pkgutil_info(id)
  (@pkginfo ||= {}).fetch(id) do |key|
    @pkginfo[key] = Utils.popen_read("/usr/sbin/pkgutil", "--pkg-info", key).strip
  end
end

.preferred_perl_versionString

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



61
62
63
64
65
66
67
68
69
# File 'os/mac.rb', line 61

def self.preferred_perl_version
  if version >= :sonoma
    "5.34"
  elsif version >= :big_sur
    "5.30"
  else
    "5.18"
  end
end

.sdk(version = nil) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



126
127
128
# File 'os/mac.rb', line 126

def self.sdk(version = nil)
  sdk_locator.sdk_if_applicable(version)
end

.sdk_for_formula(formula, version = nil, check_only_runtime_requirements: false) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'os/mac.rb', line 130

def self.sdk_for_formula(formula, version = nil, check_only_runtime_requirements: false)
  # If the formula requires Xcode, don't return the CLT SDK
  # If check_only_runtime_requirements is true, don't necessarily return the
  # Xcode SDK if the XcodeRequirement is only a build or test requirement.
  return Xcode.sdk if formula.requirements.any? do |req|
    next false unless req.is_a? XcodeRequirement
    next false if check_only_runtime_requirements && req.build? && !req.test?

    true
  end

  sdk(version)
end

.sdk_locatorObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

If a specific SDK is requested:

  1. The requested SDK is returned, if it's installed.
  2. If the requested SDK is not installed, the newest SDK (if any SDKs are available) is returned.
  3. If no SDKs are available, nil is returned.

If no specific SDK is requested, the SDK matching the OS version is returned, if available. Otherwise, the latest SDK is returned.



118
119
120
121
122
123
124
# File 'os/mac.rb', line 118

def self.sdk_locator
  if CLT.installed? && CLT.provides_sdk?
    CLT.sdk_locator
  else
    Xcode.sdk_locator
  end
end

.sdk_path(_version = nil) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns the path to an SDK or nil, following the rules set by sdk.



145
146
147
148
149
# File 'os/mac.rb', line 145

def self.sdk_path(version = nil)
  odeprecated "`MacOS.sdk_path` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
  s = sdk(version)
  s&.path
end

.sdk_path_if_needed(_version = nil) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'os/mac.rb', line 151

def self.sdk_path_if_needed(version = nil)
  odeprecated "`MacOS.sdk_path_if_needed` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
  # Prefer CLT SDK when both Xcode and the CLT are installed.
  # Expected results:
  # 1. On Xcode-only systems, return the Xcode SDK.
  # 2. On Xcode-and-CLT systems where headers are provided by the system, return nil.
  # 3. On CLT-only systems with no CLT SDK, return nil.
  # 4. On CLT-only systems with a CLT SDK, where headers are provided by the system, return nil.
  # 5. On CLT-only systems with a CLT SDK, where headers are not provided by the system, return the CLT SDK.

  return unless sdk_root_needed?

  sdk_path(version)
end

.sdk_root_needed?Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


96
97
98
99
100
101
102
103
104
105
106
# File 'os/mac.rb', line 96

def self.sdk_root_needed?
  odeprecated "`MacOS.sdk_root_needed?` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
  if MacOS::CLT.installed?
    # If there's no CLT SDK, return false
    return false unless MacOS::CLT.provides_sdk?
    # If the CLT is installed and headers are provided by the system, return false
    return false unless MacOS::CLT.separate_header_package?
  end

  true
end

.system_dir?(dir) ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


384
385
386
# File 'cask/macos.rb', line 384

def system_dir?(dir)
  SYSTEM_DIRS.include?(Pathname.new(dir).expand_path)
end

.undeletable?(path) ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:

  • (Boolean)


388
389
390
# File 'cask/macos.rb', line 388

def undeletable?(path)
  UNDELETABLE_PATHS.include?(Pathname.new(path).expand_path)
end

.versionMacOSVersion

This method is part of an internal API. This method may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This can be compared to numerics, strings, or symbols using the standard Ruby Comparable methods.

Returns:



28
29
30
31
# File 'os/mac.rb', line 28

def self.version
  odeprecated "`MacOS.version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
  @version ||= full_version.strip_patch
end