How to get the current selected Xcode and list installed
Current Selected Xcode
xcode-select
This is the most common way to get the path to the selected instance:
xcrun xcode-select --print-path# Output
/Volumes/Extended/Archives/Xcode_12.5.app/Contents/Developer
According to the documentation:
Prints the path to the currently selected developer directory. This is useful for inspection, but scripts and other tools should use xcrun(1) to locate tool inside the active developer directory.
Note: If you wonder why I prefix the xcode-select
with xcrun
command, please, check the Multiple Xcode versions or Why xcrun
is your friend article.
readlink
There is a trick to get the current selected Xcode version without the xcode-select
tool. It can be helpful in some cases, but I recommend using xcode-select
if you have no additional requirements. To check the current selected Xcode version without xcode-select
, evaluate the following command:
readlink /private/var/db/xcode_select_link# Output
/Volumes/Extended/Archives/Xcode_12.5.app/Contents/Developer
Every time you switch the default Xcode, xcode-select
changes the link to the selected version. Perhaps, this is the fastest way to obtain the path, but it is not documented, and Apple can break it with any following Xcode release.
List of installed Xcode versions
Spotlight
The easiest way to get the list of installed Xcode versions is to ask the Spotlight with the following command:
mdfind "kMDItemCFBundleIdentifier = 'com.apple.dt.Xcode'"# Output
/Volumes/Extended/Archives/Xcode_12.5.app
/Volumes/Extended/Archives/Xcode_12.4.app
/Volumes/Extended/Archives/Xcode_12.1.app
/Volumes/Extended/Archives/Xcode_12.3.app
/Volumes/Extended/Archives/Xcode_12.2.app
Note: This approach is usually not suitable for CI/Remote Builds because this is a popular option to disable Spotlight to improve performance.
system_profile
The less obvious way to get the list of installed Xcode versions is to use the system_profiler
. It registers all the versions immediately when you extract them from the xip
file.
system_profiler -json SPDeveloperToolsDataType
The problem here is the output. It is vast and looks like the following for each installed version:
{
"SPDeveloperToolsDataType" : [
{
"_name" : "spdevtools_info",
"spdevtools_apps" : {
"spinstruments_app" : "12.5 (64544.130)",
"spxcode_app" : "12.5 (18205)"
},
"spdevtools_path" : "/Volumes/Extended/Archives/Xcode_12.5.app",
"spdevtools_sdks" : {
"iOS" : {
"14.5" : "(18E182)"
},
"iOS Simulator" : {
"14.5" : "(18E182)"
},
"macOS" : {
"11.3" : "(20E214)",
"20.4" : ""
},
"tvOS" : {
"14.5" : "(18L191)"
},
"tvOS Simulator" : {
"14.5" : "(18L191)"
},
"watchOS" : {
"7.4" : "(18T187)"
},
"watchOS Simulator" : {
"7.4" : "(18T187)"
}
},
"spdevtools_version" : "12.5 (12E262)"
},
...
}
Parse the system_profiler
output with jq
You have to parse the system_profiler
output to provide meaningful information. One option is to use jq – a lightweight and flexible command-line JSON processor. For example, if you want to list paths:
system_profiler -json SPDeveloperToolsDataType | jq '.SPDeveloperToolsDataType[].spdevtools_path'# Output
"/Volumes/Extended/Archives/Xcode_12.5.app"
"/Volumes/Extended/Archives/Xcode_12.4.app"
"/Volumes/Extended/Archives/Xcode_12.3.app"
"/Volumes/Extended/Archives/Xcode_12.2.app"
"/Volumes/Extended/Archives/Xcode_12.1.app"
Or for installed versions:
system_profiler -json SPDeveloperToolsDataType | jq '.SPDeveloperToolsDataType[].spdevtools_apps.spxcode_app'# Output
"12.5 (18205)"
"12.4 (17801)"
"12.3 (17715)"
"12.2 (17535)"
"12.1 (17222)"
Tips & Tricks
How to get the installed Xcode version
When you have the path to the current selected Xcode, then you can use the following function to extract CFBundleShortVersionString
or ProductBuildVersion
:
#!/bin/sh -efunction xcodeBundleVersion() {
defaults read "${1}/../version.plist" "CFBundleShortVersionString"
}function xcodeBuildVersion() {
defaults read "${1}/../version.plist" "ProductBuildVersion"
}function xcodeVersion() {
BUNDLE_VERSION=$(xcodeBundleVersion ${1})
BUILD_VERSION=$(xcodeBuildVersion ${1})
echo "Xcode ${BUNDLE_VERSION} (${BUILD_VERSION})"
}# Note that you can replace the `xcode-select` call with other methods to extract the path
XCODE_VERSION=$(xcodeVersion $(xcrun xcode-select --print-path))
echo $XCODE_VERSION
Faster Xcode secure-archive expansion (xip
)
When you download a xip
secure archive, you can expand it from CLI with xip
tool. In this case, the validation of the archive will not be attempted. On Mac mini M1, it takes around four minutes to expand it.
% du -h Xcode_12.0.1.xip
10G Xcode_12.0.1.xip% time xip --expand Xcode_12.0.1.xip
xip: signing certificate was "Development Update" (validation not attempted)
xip: expanded items from "/Users/dive/Downloads/Xcode_12.0.1.xip"
xip --expand Xcode_12.0.1.xip 901.47s user 139.39s system 420% cpu 4:07.79 total
xcodes
– a command-line tool to install and switch between multiple versions of Xcode
I can recommend xcodes as a tool to manage your Xcode installation. The tool itself has a few benefits:
- When aria2 (a lightweight multi-protocol & multi-source command-line download utility) installed, then
xcodes
will default to use it for downloads. It uses up to 16 connections to download Xcode 3-5x faster than usual xcodes
written in Swift. Improve, fix and evolve if you need something from the tool
% xcodes installed
12.1 (12A7403) /Volumes/Extended/Archives/Xcode_12.1.app
12.2 (12B45b) /Volumes/Extended/Archives/Xcode_12.2.app
12.3 (12C33) /Volumes/Extended/Archives/Xcode_12.3.app
12.4 (12D4e) /Volumes/Extended/Archives/Xcode_12.4.app
12.5 (12E262) (Selected) /Volumes/Extended/Archives/Xcode_12.5.app
It relies on xcodereleases.com data (JSON), so you can expect delays between releases and the tool updates. But usually, it takes 10–20 minutes for an update.
Note: The tool downloads Xcode versions directly from the Apple Developer Portal. And this is the only way to do so. Please, do not download Xcode versions from third-party storages.