Followup: filed FB21570087 per Quinn's suggestion. Digging into the behavior for the write-up turned up something my original report missed.
The check in xcrun / clang is on the basename of the developer path, not the full path:
basename CommandLineTools -> accepted as a CLT install
path matches *.app/Contents/Developer -> tried as Xcode (also needs Info.plist + xcodebuild)
anything else -> rejected with the "unable to find Xcode installation" error
The parent directory isn't checked. My attempt with /Library/Developer/CommandLineTools-26.2.0 failed because of the basename, not the location.
Since DEVELOPER_DIR is a per-process env var, not the global xcode-select selection, parallel multi-version CLT actually works:
DEVELOPER_DIR=/opt/clt/17/CommandLineTools clang --version # 17.x
DEVELOPER_DIR=/opt/clt/16/CommandLineTools clang --version # 16.x
Two shells can run these concurrently and each sees its own CLT. /Library/Developer/CommandLineTools can still point at one of them as the default for things like Homebrew that don't read DEVELOPER_DIR.
I verified this end to end on macOS 15.7.3 with CLT 26.2.0: xcrun, direct clang, real compile and run, CMake --preset (AppleClang detected fine), Conan 2 install + profile detect, sccache as compiler launcher, ctest. Two parallel processes with different DEVELOPER_DIR each got their own SDK back from xcrun --show-sdk-path.
The bug is still worth fixing though:
the basename rule is undocumented xcrun behaviour and could break whenever
xcode-select -s still rejects non-standard paths even when the basename is right; only the env var path works
anything that hardcodes /Library/Developer/CommandLineTools (some Homebrew formulae, random third party scripts) won't pick up DEVELOPER_DIR
So for CI and build server setups where you control env per job, there's a workable pattern today. The broader fix is still what FB21570087 is asking for.
Topic:
Developer Tools & Services
SubTopic:
Xcode
Tags: