Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ugultopu/4adad1560d3fc94bddc489e593d04289 to your computer and use it in GitHub Desktop.

Select an option

Save ugultopu/4adad1560d3fc94bddc489e593d04289 to your computer and use it in GitHub Desktop.
Explanation of how can Command Line Tools on a macOS system can be present, even though the software package of it is missing

Summary

Sometimes, some software updates cause some package "receipts" to disappear (to be removed). This means, even though the package is actually still installed, the receipt for it will be missing. Since the receipt will be missing, one will think that the package is missing too, even though it is actually there.

In other words, this incident of removal of a package receipt without the actual removal of the package essentially disturbs the "integrity" of the native "package system" of macOS.

Details

I had neither Xcode, nor the com.apple.pkg.CLTools_Executables package:

$ pkgutil --pkg-info com.apple.pkg.CLTools_Executables
No receipt for 'com.apple.pkg.CLTools_Executables' found at '/'.
$ pkgutil --pkg-info com.apple.pkg.CLTools_Base
No receipt for 'com.apple.pkg.CLTools_Base' found at '/'.
$ ls /Applications/Xcode.app
ls: /Applications/Xcode.app: No such file or directory
$ 

Yet:

$ clang --version
Apple clang version 12.0.0 (clang-1200.0.32.28)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ git --version
git version 2.24.3 (Apple Git-128)
$ 

Confusingly, Homebrew was working without any problems and was reporting a version for Command Line Tools (CLT) when I ran brew config, meaning that it thinks that CLT are installed:

$ brew config
<rest of the `brew config` output>
CLT: 12.0.32.28
<rest of the `brew config` output>
$ 

Looking into Homebrew code, I understood that this method detects the CLT version:

def detect_version
  version = nil
  [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

where:

  • EXECUTABLE_PKG_ID is set to com.apple.pkg.CLTools_Executables
  • MAVERICKS_NEW_PKG_ID is set to com.apple.pkg.CLTools_Base

in the same file. That is, it was checking for the presence of these packages, and if neither are found, it was running the detect_version_from_clang_version method to detect the CLT version.

I used the GitHub interface for git blame on that file and understood that the detect_version_from_clang_version line was added on this commit, replacing the detect_clang_version line.

To understand when, in turn, detect_clang_version line was added, I started looking at the commit history of the file starting from that commit. While looking at the commit history, I noticed this commit message:

os/mac/xcode: fallback to clang version for detecting CLT.

For some reason pkgutil --pkgs no longer lists the CLT after the Catalina supplemental update.

Fixes #6610

I opened that commit and understood that indeed it is the commit that introduced detect_clang_version line to the detect_version method.

So, in short, most likely some software updates are causing some package receipts to be removed, even though the package is still there.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment