Swift SDK 生成器

概述

由于 Swift 支持许多不同的平台,因此交叉编译可以提高开发人员的生产力。在某些情况下,这是构建 Swift 包的唯一方法。

SE-0387 提案引入了 Swift SDK,它将交叉编译所需的所有组件捆绑在一个归档文件中,并使交叉构建像运行单个命令一样简单。

Swift SDK 作者可以手动组装这样的归档文件,但此存储库中开发的 Swift SDK 生成器的目标是尽可能地自动化此任务。如果您是平台维护者,或者希望简化您喜欢的平台的交叉编译,您可以根据您的需求定制生成器源代码,并发布新生成的 Swift SDK 供用户安装。

要求

使用 Swift SDK 需要 Swift 5.9,请首先按照 swift.org 上的安装说明进行安装。

之后,验证 experimental-sdk 命令是否可用

swift experimental-sdk list

输出将说明没有可用的 Swift SDK,或者生成您之前安装的 SDK 列表(如果您以前使用过 swift experimental-sdk install 命令)。

支持的平台和最低版本

生成器支持 macOS 作为宿主机平台,Linux 作为宿主机和目标平台。 生成器还允许在 Swift 项目官方支持的任何 Linux 发行版之间进行交叉编译。

平台 作为宿主机支持的版本 作为目标机支持的版本
macOS (arm64) ✅ macOS 13.0+
macOS (x86_64) ✅ macOS 13.0+1
Ubuntu ✅ 20.04+ ✅ 20.04 / 22.04
RHEL ✅ Fedora 392, UBI 9 ✅ UBI 9
Amazon Linux 2 ✅ 支持 ✅ 支持3
Debian 12 ✅ 支持2 ✅ 支持23

如何使用

将此存储库克隆到您选择的目录中,并将其设置为当前目录。 使用以下命令构建并运行它

swift run swift-sdk-generator make-linux-sdk

这将下载所需的组件并在 Bundles 子目录中生成 Ubuntu Jammy 的 Swift SDK。 按照生成器输出末尾打印的步骤安装新生成的 Swift SDK。

其他命令行选项可用于指定目标平台功能,例如 Linux 发行版名称、版本和目标 CPU 架构。 传递 --help 标志以查看所有可用的选项

swift run swift-sdk-generator make-linux-sdk --help

安装 Swift SDK 后,验证它是否可用于 SwiftPM

swift experimental-sdk list

最后一个命令的输出应包含 ubuntu22.04。 请注意输出中的完整 Swift SDK ID,我们随后将其称为 <generated_sdk_id>

创建一个新项目来验证 SDK 是否有效

mkdir cross-compilation test
cd cross-compilation-test
swift package init --type executable

使用 SDK 构建此项目

swift build --experimental-swift-sdk <generated_sdk_id>

验证生成的二进制文件是否与 Linux 兼容

file .build/debug/cross-compilation-test

这将产生类似于以下内容的输出

.build/debug/cross-compilation-test: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, with debug_info, not stripped

然后,您可以将此二进制文件复制到安装了 Swift 运行时库的 Docker 镜像中。 例如,对于 Ubuntu Jammy 和 Swift 5.9,这将是 swift:5.9-jammy-slim。 如果您想将二进制文件复制到任意 Ubuntu Jammy 系统,请确保除了 --experimental-swift-sdk 选项之外,还将 --static-swift-stdlib 标志传递给 swift build

从容器镜像构建 SDK

您可以将您的 SDK 基于容器镜像,例如 官方 Swift 镜像 之一。 默认情况下,以下命令将构建基于 Ubuntu Jammy 镜像的 SDK

swift run swift-sdk-generator make-linux-sdk --with-docker

要构建 RHEL 镜像,请使用 --linux-distribution-name 选项。 以下命令将构建一个基于 ubi9 的镜像

swift run swift-sdk-generator make-linux-sdk --with-docker --linux-distribution-name rhel

您还可以按名称指定基本容器镜像

swift run swift-sdk-generator make-linux-sdk --from-container-image swift:5.9-jammy
swift run swift-sdk-generator make-linux-sdk --with-docker --linux-distribution-name rhel --from-container-image swift:5.9-rhel-ubi9

包括额外的 Linux 库

如果您的项目依赖于不属于标准基本镜像的 Linux 库,您可以从包含它们的自定义容器镜像构建您的 SDK。

准备一个 Dockerfile,它派生自标准镜像之一并安装您需要的包。 此示例在 Swift 项目的 Ubuntu Jammy 镜像之上安装 SQLite 及其依赖项

FROM swift:5.9-jammy
RUN apt update && apt -y install libsqlite3-dev && apt -y clean

构建新的容器镜像

docker build -t my-custom-image -f Dockerfile .

最后,构建您的自定义 SDK

swift run swift-sdk-generator make-linux-sdk --with-docker --from-container-image my-custom-image:latest --sdk-name 5.9-ubuntu-with-sqlite

Swift SDK 分发

在前一节中生成的 .artifactbundle 目录可以打包为 .tar.gz 存档并以此形式重新分发。 此类 Swift SDK 捆绑包存档的用户可以使用 swift experimental-sdk install 命令轻松安装它,该命令支持本地文件系统路径和公共 http://https:// URL 作为参数。

贡献

有几种方法可以为 Swift SDK 生成器做出贡献。 要了解管理 Swift 项目贡献的策略、最佳实践以及设置开发环境的说明,请阅读贡献者指南

如果您有兴趣添加对新平台的支持,请先在此存储库上打开一个 issue,以便在开始实施之前讨论最佳实施策略。

报告问题

如果您在使用 Swift SDK 生成器时遇到任何问题,可以寻求帮助。 我们推荐

报告问题时,请遵循 bug 报告指南,可以在贡献指南中找到它们。

如果您不方便与列表分享您的问题,可以在CODEOWNERS中找到代码所有者的联系方式; 但是,Swift 论坛通常是寻求帮助的最佳场所。

许可

版权所有 2022 - 2024 Apple Inc. 和 Swift 项目作者。 在 Apache License v2.0 下获得许可,并附带运行时库例外。

有关许可信息,请参阅 https://swiftlang.cn/LICENSE.txt

有关 Swift 项目作者,请参阅 https://swiftlang.cn/CONTRIBUTORS.txt

脚注

  1. 由于 LLVM 项目未在 x86_64 上的 macOS 上提供 lld 的预构建二进制文件,因此它将由生成器从源代码自动构建,这会使其运行时间在最新的硬件上至少增加 15 分钟。 您还需要预先安装 CMake 和 Ninja(例如通过 brew install cmake ninja)。

  2. 这些发行版仅受 Swift 5.10.1 及更高版本支持,作为宿主机和目标平台。 2 3

  3. 从技术上讲,这些版本受支持,但需要自定义命令和 Docker 容器来构建 Swift SDK,因为生成器不会自动下载这些发行版的依赖项。 请参阅 issue #138 2