Swift 的编译器驱动程序是一个程序,它协调将 Swift 源代码编译成各种编译结果:可执行文件、库、目标文件、Swift 模块和接口等。它是从命令行调用以构建 Swift 代码的程序(即 swift
或 swiftc
),并且通常由构建系统(例如 Swift Package Manager (SwiftPM) 或 Xcode 的构建系统)代表开发者调用。
swift-driver
项目是 Swift 编译器驱动程序的一个新的实现,旨在取代 现有的驱动程序,采用更具可扩展性、可维护性和健壮性的代码库。该项目的具体目标包括:
注意: 目前,swift-driver 仅与 swift.org 上的 trunk 开发快照兼容。
构建 swift-driver
的首选方法是使用 Swift 包管理器。
在大多数平台上,您可以使用以下命令构建:
$ swift build
但是,在 Windows 上,开发人员必须完成一些额外的工作。
由于 Package.resolved
引用的 swift-tools-support-core 的默认版本,我们必须首先更新包依赖项。
swift package update
然后,我们可以使用以下命令构建包:
swift build -Xcc -I -Xcc "%SystemDrive%\Library\sqlite-3.38.0\usr\include" -Xlinker -L -Xlinker "%SystemDrive%\Library\sqlite-3.38.0\usr\lib" -Xlinker "%SDKROOT%\usr\lib\swift\windows\x86_64\swiftCore.lib"
由于 SQLite3 是一个系统库依赖项,并且没有单一的头文件和库搜索路径,因此开发人员必须指定它。如果该库不在指定的位置,则可能需要调整 SQLite3 的路径。此外,由于 Swift 包管理器不区分 C/C++ 和 Swift 目标,并且使用 Swift 驱动程序作为链接器驱动程序,因此我们必须手动将 Swift 运行时链接到所有目标中。
要使用 swift-driver
代替现有的 Swift 驱动程序,请创建从 swift
和 swiftc
到 swift-driver
的符号链接。
ln -s /path/to/built/swift-driver $SOME_PATH/swift
ln -s /path/to/built/swift-driver $SOME_PATH/swiftc
可以通过覆盖 SWIFT_EXEC
以引用上面创建的 swiftc
符号链接,以及 SWIFT_DRIVER_SWIFT_FRONTEND_EXEC
以引用原始的 swift-frontend
来使用新的 Swift 驱动程序构建 Swift 包,例如:
SWIFT_EXEC=$SOME_PATH/swiftc SWIFT_DRIVER_SWIFT_FRONTEND_EXEC=$TOOLCHAIN_PATH/bin/swift-frontend swift build
类似地,可以通过添加一个自定义构建设置(通常在项目级别)来在 Xcode 中使用新的 Swift 驱动程序,该设置名为 SWIFT_EXEC
,引用 $SOME_PATH/swiftc
,并将 -driver-use-frontend-path $TOOLCHAIN_DIR/usr/bin/swiftc
添加到 Other Swift Flags
。
swift-driver
也可以使用 CMake 构建,这建议在 Swift 包管理器尚不可用的环境中使用。这样做需要首先构建几个依赖项,所有这些都使用 CMake。
-DLLBUILD_SUPPORT_BINDINGS="Swift"
和 -DCMAKE_OSX_ARCHITECTURES=x86_64
(如果在 Intel 上构建)配置 CMakecmake -B <llbuild-build-dir> -G Ninja <llbuild-source-dir> -DLLBUILD_SUPPORT_BINDINGS="Swift" -DCMAKE_OSX_ARCHITECTURES=x86_64
一旦构建了这些依赖项,就可以构建 swift-driver
本身
cmake -B <swift-driver-build-dir> -G Ninja <swift-driver-source-dir> -DTSC_DIR=<swift-tools-support-core-build-dir>/cmake/modules -DLLBuild_DIR=<llbuild-build-dir>/cmake/modules -DArgumentParser_DIR=<swift-argument-parser-build-dir>
cmake --build <swift-driver-build-dir>
新的 Swift 驱动程序仍在开发中,任何有兴趣的人都可以贡献很多地方!本节涵盖测试、各种开发技巧和窍门,以及一个粗略的开发计划,展示了仍需要完成的工作。
有关驱动程序的概念性概述,请参见 Swift 驱动程序、编译模型和命令行体验。要了解更多关于内部的信息,请参见 驱动程序设计 & 内部 和 可解析的驱动程序输出。
使用命令行 SwiftPM 或 Xcode 进行测试。
$ swift test --parallel
集成测试运行成本很高,默认情况下禁用。使用 SWIFT_DRIVER_ENABLE_INTEGRATION_TESTS
环境变量启用它们。在 Xcode 中,您可以在 scheme 的测试操作中设置此变量。
$ SWIFT_DRIVER_ENABLE_INTEGRATION_TESTS=1 swift test --parallel
一些集成测试在 Swift 工作副本中运行 lit 测试套件。要启用这些测试,请克隆 Swift 及其依赖项并使用 build-script 构建它们,然后同时设置 SWIFT_DRIVER_ENABLE_INTEGRATION_TESTS
和 SWIFT_DRIVER_LIT_DIR
,无论是在您的 Xcode scheme 中还是在命令行中
$ SWIFT_DRIVER_ENABLE_INTEGRATION_TESTS=1 \
SWIFT_DRIVER_LIT_DIR=/path/to/build/Ninja-ReleaseAssert/swift-.../test-... \
swift test -c release --parallel
swift-driver
持续集成针对在 swift.org/download 上发布的最新 Trunk 开发快照运行。
当开发与底层 swift
编译器前端有复杂交互的补丁时,谨慎的做法是确保 swift-driver
测试也通过针对当前的 tip-of-trunk swift
。为此,请针对 github.com/apple/swift 创建一个空的 pull request,并针对您的 swift-driver
pull request # 执行跨存储库测试,例如
Using:
apple/swift-driver#208
@swift-ci smoke test
@swift-ci 跨存储库测试工具在 此处 描述。
安装工具链后,需要告诉 Xcode 使用它。这可能意味着两件事,使用工具链构建驱动程序和告诉驱动程序在运行时使用工具链。
使用工具链进行构建很简单,在 Xcode 中设置工具链:菜单栏 > Xcode > Toolchains > 选择您的工具链
运行驱动程序需要设置 TOOLCHAINS 环境变量。 这告诉 xcrun 使用哪个工具链(在 darwin 上使用 xcrun 查找工具)。此变量是工具链的名称,而不是路径(例如:Swift Development Snapshot
)。重要提示:xcrun 查找的优先级低于 SWIFT_EXEC_*_EXEC 系列环境变量、tools 目录以及与驱动程序位于同一目录中的任何工具(包括安装在工具链中的驱动程序)。即使 TOOLCHAINS 不是最高优先级,它也是使用自定义工具链运行 xctest 套件的便捷方法。
在 macOS 上进行开发而无法快速访问 Linux 机器时,使用 Linux Docker 通常有助于调试。
要启动并运行 docker,请执行以下操作
docker pull swift
。$ docker run -v /path/to/swift-driver:/home/swift-driver \
--cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
--security-opt apparmor=unconfined -it swift:latest bash
$ apt-get update
$ apt-get install libsqlite3-dev
$ apt-get install libncurses-dev
/home/swift-driver
并运行 swift test --parallel
来运行您的测试。Options.swift
包含驱动程序可以解析的完整选项集,它是从 Swift 编译器中的选项表 自动生成的。如果您需要重新生成 Options.swift
,您需要 构建 Swift 编译器,然后构建 makeOptions
程序,并使用一个 -I
,该 -I
允许找到生成的 Options.inc
,例如
$ swift build -Xcc -I/path/to/build/Ninja-Release/swift-.../include -Xcc -I/path/to/build/Ninja-Release/llvm-.../include -Xcc -I/path/to/source/llvm-project/llvm/include --product makeOptions
然后,运行 makeOptions
并将输出重定向以覆盖 Options.swift
$ .build/path/to/makeOptions > Sources/SwiftOptions/Options.swift
新 Swift 驱动程序的目标是提供现有驱动程序的直接替代品,这意味着在可以弃用和删除现有 Swift 驱动程序之前,需要实现一个固定的初始功能集。以下开发计划涵盖了该功能集,并描述了许多可以改进 Swift 驱动程序的任务---从代码清理到改进测试、实现缺失的功能以及与现有系统集成。
FIXME:
或 TODO:
:有很多小事需要改进!Error
添加有用的描述Options.swift
中选项的完整“覆盖”。驱动程序中是否检查了每个选项?OptionAlias
,这样我们就不会犯错误(例如)在我们翻译选项时请求别名选项?makeOptions.cpp
更好的方法,将 Swift 存储库 中的命令行选项转换为 Options.swift
。DarwinToolchain
也处理 iOS、tvOS、watchOSGenericUnixToolchain
工具链以使其工作WindowsToolchain
OutputFileMap
实现,以统一处理所有文件类型build-script
构建 swift-driver
。build-toolchain
将 swift-driver
安装为主要驱动程序,以便我们可以使用新驱动程序测试完整的工具链基于 libSwiftDriver,swift-build-sdk-interfaces
是一个工具,用于批量构建来自 SDK 的所有 Swift 文本接口 (.swiftinterface
) 到二进制模块 (.swiftmodule
)。例如,以下命令查找来自 MacOSX SDK 的所有 Swift 文本接口,将它们全部构建为二进制模块,并将特定于模块的错误日志输出到给定目录中。
$SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk SWIFT_EXEC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc swift-build-sdk-interfaces -o /tmp/outputs -v -log-path /tmp/logs
swift-build-sdk-interfaces
在哪里找到要使用的 Swift 编译器欢迎并鼓励大家为 swift-driver 做出贡献!请参阅 Swift 贡献指南。
提交 pull request 之前,请确保您已经测试过您的更改,并且它们符合 Swift 项目的代码贡献指南。
为了成为一个真正伟大的社区,Swift.org 需要欢迎来自各行各业、拥有不同背景和广泛经验的开发者。一个多元化和友好的社区将拥有更多的好主意、更独特的视角,并产生更优秀的代码。我们将努力使 Swift 社区欢迎所有人。
为了明确我们对社区成员的期望,Swift 采用了贡献者公约定义的行为准则。该文档被许多开源社区使用,我们认为它很好地表达了我们的价值观。更多信息请参阅行为准则。