Know your Mac
Inspect the active developer directory
Find the Apple developer tools selected for command-line builds and recognize when Xcode changes the selected path.
10 minute lesson
Apple command-line builds use one active developer directory. Every compile that touches Apple tooling — a C extension for Python, a native npm module, a Ruby gem — resolves its compiler and SDK through that single path.
It may point to the standalone Command Line Tools package or to an installed Xcode application. The two ship different SDK versions, so knowing which one is active explains a lot of “works on my machine” build differences.
Check the selection
xcode-select --print-path
xcrun --find clang
clang --version
With only the Command Line Tools installed you get:
/Library/Developer/CommandLineTools
/Library/Developer/CommandLineTools/usr/bin/clang
Apple clang version 17.0.0 (clang-1700.0.13.3)
With Xcode installed, the first line usually reads /Applications/Xcode.app/Contents/Developer instead. Installing Xcode after the Command Line Tools often flips the selection without asking you.
xcrun resolves tools inside the selected developer directory. That is why xcrun --find clang and plain command -v clang can disagree: the first follows the selection, the second follows your PATH.
When the selection breaks
After a macOS upgrade, the tools sometimes vanish while the selection stays. The symptom is loud:
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools),
missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
That is a missing package, not a wrong selection: reinstall the Command Line Tools. If the path instead points to an Xcode you deleted, that is a wrong selection: fix it with sudo xcode-select -s /Library/Developer/CommandLineTools or reset to the default search order with sudo xcode-select --reset.
Record it, don’t thrash it
Record the xcode-select --print-path output with build reports and in your setup notes. When a native build fails on one machine and passes on another, comparing this path is the first diff to run.
Do not switch it globally just to silence an error before you know which project needs which SDK. The selection is machine-wide: pointing it at a different Xcode to fix project A can quietly break project B’s builds the same afternoon.
Lesson completed