Module: OS::Mac::CLT Private

Defined in:
os/mac/xcode.rb

Overview

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.

Helper module for querying macOS Command Line Tools information.

Constant Summary collapse

EXECUTABLE_PKG_ID =

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.

The original Mavericks CLT package ID

"com.apple.pkg.CLTools_Executables"
MAVERICKS_NEW_PKG_ID =

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.

obsolete

"com.apple.pkg.CLTools_Base"
PKG_PATH =

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.

"/Library/Developer/CommandLineTools"

Class Method Summary collapse

Class Method Details

.below_minimum_version?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)


414
415
416
417
418
# File 'os/mac/xcode.rb', line 414

def self.below_minimum_version?
  return false unless installed?

  version < minimum_version
end

.detect_clang_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:



429
430
431
432
# File 'os/mac/xcode.rb', line 429

def self.detect_clang_version
  version_output = Utils.popen_read("#{PKG_PATH}/usr/bin/clang", "--version")
  version_output[/clang-(\d+(\.\d+)+)/, 1]
end

.detect_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:



457
458
459
460
461
462
463
464
465
466
467
# File 'os/mac/xcode.rb', line 457

def self.detect_version
  version = T.let(nil, T.nilable(String))
  [EXECUTABLE_PKG_ID, MAVERICKS_NEW_PKG_ID].each do |id|
    next unless File.exist?("#{PKG_PATH}/usr/bin/clang")

    version = MacOS.pkgutil_info(id)[/version: (.+)$/, 1]
    return version if version
  end

  detect_version_from_clang_version
end

.detect_version_from_clang_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:



435
436
437
438
439
440
# File 'os/mac/xcode.rb', line 435

def self.detect_version_from_clang_version
  clang_version = detect_clang_version
  return if clang_version.nil?

  MacOS::Xcode.detect_version_from_clang_version(Version.new(clang_version))
end

.installation_instructionsString

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:



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'os/mac/xcode.rb', line 312

def self.installation_instructions
  if MacOS.version == "10.14"
    # This is not available from `xcode-select`
    <<~EOS
      Install the Command Line Tools for Xcode 11.3.1 from:
        #{Formatter.url(MacOS::Xcode::APPLE_DEVELOPER_DOWNLOAD_URL)}
    EOS
  elsif OS::Mac.version.prerelease?
    <<~EOS
      Install the Command Line Tools for Xcode #{minimum_version.split(".").first} from:
        #{Formatter.url(MacOS::Xcode::APPLE_DEVELOPER_DOWNLOAD_URL)}
    EOS
  else
    <<~EOS
      Install the Command Line Tools:
        xcode-select --install
    EOS
  end
end

.installation_then_reinstall_instructionsString

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:



365
366
367
368
369
370
# File 'os/mac/xcode.rb', line 365

def self.installation_then_reinstall_instructions
  <<~EOS
    #{installation_instructions}
    #{reinstall_instructions}
  EOS
end

.installed?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 true even if outdated tools are installed.

Returns:

  • (Boolean)


282
283
284
# File 'os/mac/xcode.rb', line 282

def self.installed?
  !version.null?
end

.latest_clang_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.

Bump these when the new version is distributed through Software Update and our CI systems have been updated.

Returns:



375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
# File 'os/mac/xcode.rb', line 375

def self.latest_clang_version
  case MacOS.version
  when "26" then "1700.3.19.1"
  when "15" then "1700.0.13.5"
  when "14" then "1600.0.26.6"
  when "13" then "1500.1.0.2.5"
  when "12"    then "1400.0.29.202"
  when "11"    then "1300.0.29.30"
  when "10.15" then "1200.0.32.29"
  when "10.14" then "1100.0.33.17"
  when "10.13" then "1000.10.44.2"
  when "10.12" then "900.0.39.2"
  else              "800.0.42.1"
  end
end

.minimum_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.

Bump these if things are badly broken (e.g. no SDK for this macOS) without this. Generally this will be the first stable CLT release on that macOS version.

Returns:



395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# File 'os/mac/xcode.rb', line 395

def self.minimum_version
  macos = MacOS.version
  case macos
  when "15" then "16.0.0"
  when "14" then "15.0.0"
  when "13" then "14.0.0"
  when "12" then "13.0.0"
  when "11" then "12.5.0"
  when "10.15" then "11.0.0"
  when "10.14" then "10.0.0"
  when "10.13" then "9.0.0"
  when "10.12" then "8.0.0"
  when "10.11" then "7.3.0"
  else
    "#{macos}.0.0"
  end
end

.outdated?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)


421
422
423
424
425
426
# File 'os/mac/xcode.rb', line 421

def self.outdated?
  clang_version = detect_clang_version
  return false unless clang_version

  ::Version.new(clang_version) < latest_clang_version
end

.provides_sdk?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)


292
293
294
# File 'os/mac/xcode.rb', line 292

def self.provides_sdk?
  version >= "8"
end

.reinstall_instructions(reason: "resolve your issues") ⇒ 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:

  • reason (String) (defaults to: "resolve your issues")

Returns:



333
334
335
336
337
338
339
340
341
342
343
# File 'os/mac/xcode.rb', line 333

def self.reinstall_instructions(reason: "resolve your issues")
  <<~EOS
    If that doesn't #{reason}, run:
      sudo rm -rf /Library/Developer/CommandLineTools
      sudo xcode-select --install

    Alternatively, manually download them from:
      #{Formatter.url(MacOS::Xcode::APPLE_DEVELOPER_DOWNLOAD_URL)}.
    You should download the Command Line Tools for Xcode #{MacOS::Xcode.latest_version}.
  EOS
end

.sdk(version = nil) ⇒ SDK?

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:



302
303
304
# File 'os/mac/xcode.rb', line 302

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

.sdk_locatorCLTSDKLocator

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:



297
298
299
# File 'os/mac/xcode.rb', line 297

def self.sdk_locator
  @sdk_locator ||= T.let(CLTSDKLocator.new, T.nilable(OS::Mac::CLTSDKLocator))
end

.sdk_path(version = nil) ⇒ 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:



307
308
309
# File 'os/mac/xcode.rb', line 307

def self.sdk_path(version = nil)
  sdk(version)&.path
end

.separate_header_package?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)


287
288
289
# File 'os/mac/xcode.rb', line 287

def self.separate_header_package?
  version >= "10" && MacOS.version >= "10.14"
end

.update_instructionsString

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:



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'os/mac/xcode.rb', line 346

def self.update_instructions
  return installation_instructions if OS::Mac.version.prerelease?

  software_update_location = if MacOS.version >= "13"
    "System Settings"
  elsif MacOS.version >= "10.14"
    "System Preferences"
  else
    "the App Store"
  end

  <<~EOS
    Update them from Software Update in #{software_update_location}.

    #{reinstall_instructions(reason: "show you any updates")}
  EOS
end

.version::Version

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.

Version string (a pretty long one) of the CLT package. Note that the different ways of installing the CLTs lead to different version numbers.

Returns:



448
449
450
451
452
453
454
# File 'os/mac/xcode.rb', line 448

def self.version
  if @version ||= T.let(detect_version, T.nilable(String))
    ::Version.new @version
  else
    ::Version::NULL
  end
end