Skip to content
C.W.K.
Stream
Lesson 02 of 06 · published

The Toolchain You Actually Have

~14 min · platform-map, xcode, command-line-tools, versions

Level 0Bundle Opener
0 XP0/81 lessons0/17 achievements
0/100 XP to next level100 XP to go0% complete
"Four different numbers all get called 'the Swift version'. Only one of them is."

Xcode, or Just the Command Line Tools

A Mac can hold two kinds of Apple toolchain. Xcode is the full thing: the Swift compiler, SwiftPM, xcodebuild, every platform SDK (macOS, iOS, watchOS), the simulators, Instruments, and the signing machinery that talks to your developer account. The Command Line Tools are a much smaller install: a compiler, SwiftPM, git, the macOS SDK — and nothing for iOS, no simulators, no xcodebuild archive or upload.

The difference is not academic. A family Mac that only had the Command Line Tools could build a SwiftPM app fine and then failed every swift test with no such module 'XCTest', and on those tools 'Testing' was missing too. The app was not broken. The toolchain simply did not carry the test frameworks. Current Command Line Tools do ship Swift Testing, but never XCTest. That Mac's repositories now keep a small self-test executable for exactly that case, which you will meet in the packages track.

xcode-select -p tells you which one your shell is using. xcrun finds every tool (swift, codesign, simctl, notarytool) inside that selected developer directory, which is why scripts call xcrun simctl instead of a hard-coded path.

Four Numbers That Are Not the Same Number

NumberWhat it controlsWhere it lives
Compiler versionWhich Swift features and diagnostics exist at all (6.3.3 on this quest's build Mac)swift --version
Language modeHow the compiler interprets your source: Swift 5 or Swift 6 rules, per targetswiftLanguageModes / SWIFT_VERSION
SDK versionWhich APIs you are allowed to call (26.x with Xcode 26)xcrun --sdk iphoneos --show-sdk-version
Deployment targetThe oldest OS you promise to run on (macOS 14 / iOS 17 / watchOS 10 in this family)platforms: / deploymentTarget

Mixing these up produces confident nonsense. "We're on Swift 6" can mean a 6.x compiler compiling everything in Swift 5 mode — which is exactly the situation that let a real crash through. A new API from the 26 SDK does not even compile against an iOS 17 deployment target until you guard it with if #available, and that guard is what keeps an iOS 17 device from reaching a symbol it does not have.

Apple Moves the Floor Every Year

Apple ships a new Xcode, SDK and Swift release every autumn and then raises the minimum for uploads. Since April 28, 2026, iOS, iPadOS, tvOS, visionOS and watchOS apps uploaded to App Store Connect must be built with Xcode 26 or later and a 26 SDK. Apple's notice does not list macOS. Your deployment target can stay old; your build toolchain cannot. This quest is pinned to what the family actually ships with: Swift 6.3.3 and Xcode 26.6 on macOS 26. Swift 6.4 and Xcode 27 were announced at WWDC 2026 — when they reach the build Mac, re-check every version-specific claim against the release notes, not against memory.

Code

Print the four numbers (and which toolchain is selected)·bash
xcode-select -p                         # /Applications/Xcode.app/Contents/Developer, or CommandLineTools
swift --version                         # compiler version
xcodebuild -version                     # Xcode version (fails on Command Line Tools only)
xcrun --sdk macosx --show-sdk-version   # SDK you compile against
xcrun --sdk iphoneos --show-sdk-version
sw_vers -productVersion                 # the OS this Mac runs (not your deployment target)

# Switch the selected Xcode (needs an admin password):
#   sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

External links

Exercise

Run the command block on your Mac and write down all four numbers for the Spark project you are about to start: compiler version, the language mode you will declare, the SDK you have, and the deployment targets you choose for macOS, iOS and watchOS. Then write one sentence for each deployment target explaining what it forbids you from calling without an availability check.
Hint
If xcodebuild -version fails, you are on the Command Line Tools. That is fine for the first tracks and a hard stop for the iOS, watch and TestFlight tracks — install Xcode before you get there.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.