xcodebuild、xcrun 和 swift 命令行工具之间有什么区别?

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

我们可以通过多个命令从命令行构建 运行 Swift code/projects 而无需使用 Xcode。我听说 xcodebuildxcrunswift 用于 Xcode 开发。我确实在使用 fastlane,但我并不真正了解在引擎盖下为其提供动力的工具。

我是一名 iOS 开发人员,使用 Mac。我使用 Xcode 进行开发,所以我以前没有使用过这些命令行工具。

每个命令之间有什么区别?在某些情况下,我最好还是使用其中一种?

Tl;DR

xcodebuildxcrun 帮助在无头上下文中构建 Xcode 项目,例如在 CI 设置中。 swift 是 Swift REPL,主要用于服务器应用程序上的 Swift。因此,我们可以在不了解或经常使用移动应用程序开发中的工具的情况下构建应用程序。我们在后台使用 xcodebuildxcrun 与 Xcode 交互,尽管我们没有意识到,因为它们捆绑在 Xcode's Command Line tools 中(文档存档,但仍然相关) .

fastlane 是一个示例 CI 工具,它使用这些工具自动执行构建过程、证书签名以及与 App Store Connect 的接口。

xcodebuild

xcodebuild 是 Xcode 的捆绑命令行工具包的一部分。来自 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 有很多选项和用例。这些选项等同于 Xcode IDE 中的某些用户操作。用法示例:

xcodebuild -workspace MyWorkspace.xcworkspace -scheme MyScheme

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

在上面的命令中,我们在没有Xcode的情况下构建工作区,内部使用Xcode 运行s进行编译。 Xcode 只能安装在 macOS 上,我们使用它的命令行工具也有同样的限制,包括 xcodebuildxcrun.

xc运行

xcrun 是 Xcode CLI 工具的另一个 Xcode 命令行工具部分。来自 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 也常与 Xcode-select 一起使用,以在同一台机器上管理多个 Xcode 版本。 Xcode 的每个版本都捆绑了自己的开发工具,我们可以使用 xcrun 获取它们的当前路径:

xcrun xcode-select --print-path

swift

swift 是 Swift REPL。 swift 是一个包含 Swift 工具链的命令行工具,但也可以安装在 Xcode 捆绑工具之外。 swiftxcodebuildxcrun 不同,因为它是 Swift 而不是 C 编译的。 swift 在 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.

一个REPL本质上是一个交互式编译环境或shell。首先,REPL 读取代码,然后对其求值、打印并重复该过程。可以想象,与 IDE 相比,我们可以使用 REPL 进行开发的要少得多。但是,除了 iOS、watchOS 和 macOS 开发之外,Swift 还有其他用例。

swift 包括 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 台机器。

为了更广泛的采用,Apple 已在 Xcode 尚不可用的不同操作系统上提供 swift。 Swift 现在还有 Docker support 和 Windows。 Docker 使我们能够在任何机器上 运行 swift 而不管底层 OS。 swift 在这些应用程序中用作 脚本 语言。

SoS 奖金

swift 主要用于 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 和 Ruby 用于 JSON 序列化任务的效率。 Swift 在极少数任务中与 Java 相当,但这可能会随着语言和生态系统的发展而改变。

xcrun

xcrun 视为 方便的前缀 以调用当前活动 中的各种命令行工具 Xcode 工具链。

多个 Xcode 工具链可以安装在同一台机器上(例如最新版本、测试版 and/or 旧版本)。使用 xcode-select 设置使用哪个 Xcode 工具链路径。或者,可以通过设置环境变量 SDKROOTDEVELOPER_DIR

来指定活动的开发人员工具链
### open 'bin' directory for the currently active Xcode toolchain 
open `xcode-select --print-path`/usr/bin

可以使用 xcrun 调用的工具包括:

  • xcrun simctl <subcommand>~iOS模拟器控制
  • xcrun xcodebuild … ~ build/test Xcode 项目和工作区
  • xcrun xctrack <commands> [options] ~ 记录、导入和导出 Instruments .trace 文件
xcrun not_a_tool  help

# xcrun: error: 
#   sh -c '/Applications/Xcode.app/…/bin/xcodebuild 
#         -sdk /Applications/Xcode.app/…/MacOSX.sdk 
#         -find not_a_tool 2> /dev/null' 
# failed with exit code 17664: (null) (errno=Invalid argument)

xcodebuild

xcodebuild 视为专门用于 利用多个其他工具来管理整个项目构建过程的单一命令行工具 xcodebuild 的调用将执行许多任务,就像 Xcode GUI 菜单中的 BuildTest 在创建 and/or 测试项目时所做的那样。

xcodebuild -help

注意:xcodebuild可以在没有程序的情况下调用xcrun

xcrun xcodebuild -version
# Xcode 13.2.1
# Build version 13C100

xcodebuild -version 
# Xcode 13.2.1
# Build version 13C100

swift

swift(本身)视为 swiftc 编译器的解释型、交互式、可编写脚本的“REPL”版本。

然后,扩大范围,将 swift 视为不需要 Xcode 存在的扩展生态系统的基础(除非需要 AppleOS SDK 来针对 Apple 硬件) .

swift --help

# SUBCOMMANDS (swift <subcommand> [arguments]):
#   build:   SwiftPM - Build sources into binary products
#   package: SwiftPM - Perform operations on Swift packages
#   run:     SwiftPM - Build and run an executable product
#   test:    SwiftPM - Build and run tests

命令行示例

> swift
Welcome to Swift version 5.5.2-dev.
Type :help for assistance.
  1> 8 + 9 
$R0: Int = 17
  2> :quit

Note: , thus : preceeds commands like help and quit during the REPL session.

Swift 脚本示例

脚本example_script.swift文件:

#!/usr/bin/swift

// File: example_script.swift
// reminder: chmod to executable before invoking the script

import Foundation

func printHelp() {
    print("Please add an argument to the command line. Thanks.")
}

// --- main ---
if CommandLine.argc < 2 {
    printHelp()
} else {
    for i: Int in 1 ..< Int(CommandLine.argc) {
        print( CommandLine.arguments[i] )
    }
}

解释和编译的脚本执行:

ls -l example_script.swift 
# -rwxr--r--@ 1 user staff  321 Dec 30 16:56 example_script.swift

./example_script.swift 
# Please add an argument to the command line. Thanks.

./example_script.swift a bcd
# a
# bcd

## Let's compile the script...
swiftc example_script.swift 

ls -l ex*
# -rwxr-xr-x  1 user staff  55136 Dec 30 16:57 example_script
# -rwxr--r--  1 user staff    321 Dec 30 16:56 example_script.swift

./example_script
# Please add an argument to the command line. Thanks.

./example_script xyx
# xyz  

REPL:读取评估打印循环