iosswiftxcodemacosxcodebuild

What are the differences between xcodebuild, xcrun and swift command line tools?


We can build and run Swift code/projects from the command line via multiple commands without using Xcode. I have heard of xcodebuild, xcrun and swift used for Xcode development. I do use fastlane but I don't really understand the tools powering it under the hood.

I am an iOS developer who uses a Mac. I develop using Xcode so I haven't used these command-line tools before.

What are the differences between each command? Are there any cases where I'd be better off using one over the other?


Solution

  • Tl;DR

    xcodebuild and xcrun help build Xcode projects in a headless context, for example in CI setups. swift is the Swift REPL and is largely used for Swift on Server apps. As such, we can build apps without knowing about or using the tools regularly in mobile app development. We use xcodebuild and xcrun under the hood interacting with Xcode even though we don't realise it because they're bundled in Xcode's Command Line tools (documentation archive, but still relevant).

    fastlane is an example CI tool that automates the build process, certificate signing, and interfacing with App Store Connect, using these tools.

    xcodebuild

    xcodebuild is part of Xcode's bundled command-line tools package. From the manpages:

    build Xcode projects and workspaces

    xcodebuild builds one or more targets contained in an Xcode project, or builds a scheme contained in an Xcode workspace or Xcode project.

    xcodebuild has lots of options and use cases. The options are equivalent to certain user actions within the Xcode IDE. Example usage:

    xcodebuild -workspace MyWorkspace.xcworkspace -scheme MyScheme
    

    Builds the scheme MyScheme in the Xcode workspace MyWorkspace.xcworkspace.

    In the command above, we build the workspace without Xcode, using what Xcode runs internally for compilation. Xcode can only be installed on macOS and we have the same limitations for using its command-line tools, including xcodebuild and xcrun.

    xcrun

    xcrun is another Xcode command-line tool part of Xcode's CLI tools. From the manpages:

    run or locate development tools

    xcrun provides a means to locate or invoke coexistence- and platform-aware developer tools from the command-line, without requiring users to modify makefiles or otherwise take inconvenient measures to support multiple Xcode toolchains.

    xcrun [-sdk SDK] -find <tool_name>
    

    xcrun is also commonly used with Xcode-select to manage multiple Xcode versions on the same machine. Every version of Xcode comes bundled with its own development tools, and we can use xcrun to get the current path to them:

    xcrun xcode-select --print-path
    

    swift

    swift is the Swift REPL. swift is a command-line tool that includes the Swift toolchain but can also be installed outside of the Xcode bundled tools. swift is different from xcodebuild and xcrun because it is compiled Swift rather than C. swift is not well documented in the MacOS manpages documentation, however, Apple has documented these tools on its blog:

    Xcode 6.1 introduces yet another way to experiment with Swift in the form of an interactive Read Eval Print Loop, or REPL.

    A REPL is essentially an interactive compilation environment or shell. First, the REPL reads code, then evaluates it, prints, and repeats the process. As you can imagine, there is much less we can develop using a REPL compared to an IDE. However, there are other use cases for Swift than iOS, watchOS, and macOS development.

    swift includes the standard library and doesn't include libraries such as Foundation and UIKit. These Swift libraries are almost certainly needed for iOS or macOS development, so we can't develop apps using the swift REPL alone. However, Swift on Server projects regularly use swift to run Swift code on Linux and even Windows machines.

    For wider adoption, Apple has made swift available on different Operating Systems where Xcode is not readily available. Swift now also has Docker support and Windows. Docker enables us to run swift on any machine regardless of the underlying OS. swift in these applications serves as a scripting language.

    Bonus notes for SoS

    swift is used largely for Swift on Server. Swift on Server has great performance for server applications, with a lower memory footprint, fast startup time, and deterministic performance. Although it is not quite as fast as .NET core for some tasks, this is because Swift is much safer with a rigorous type system, garbage collection with ARC, and fewer optimisations for server-specific apps. Many early adopters praise the improved language type system, memory efficiency, and algorithmic performance. In fact, Swift vapor is comparable to Python and Ruby in efficiency for JSON Serialization tasks. Swift is comparable to Java in very few tasks, but this is likely to change as the language and ecosystem grow.