Bazel 的 Swift Package Manager 规则
本仓库包含一个 Bazel 规则集,可用于下载、构建和使用 Swift 包。本仓库中的规则使用 rules_swift、 rules_apple 和原生 C/C++ 规则集来构建外部 Swift 包,使 Swift 包的产品和目标可作为 Bazel 目标使用。
本仓库旨在完全替代 rules_spm,并提供工具以简化 Bazel 工作区内的 Swift 开发。
目录
- 文档
- 先决条件
- 快速入门
- 使用 Swift 包注册表
- 技巧与窍门
文档
先决条件
Mac OS
请确保已安装 Xcode。
Linux
您需要 安装 Swift。请确保
运行 swift --version 正常工作。
请记住,rules_swift 期望使用
clang。因此,
在运行 Bazel 之前,您需要指定 CC=clang。
最后,通过确保 Bazel 操作中存在包含 Swift 二进制的 PATH,帮助 rules_swift 和 rules_swift_package_manager 找到 Swift 工具链。
cat >>local.bazelrc <<EOF
build --action_env=PATH
EOF
这种方法对于在 Ubuntu 运行器上使用 Github actions 成功执行示例是必要的。有关更多详细信息,请参阅 CI GitHub workflow。
快速入门
以下内容简要介绍了如何设置和使用本仓库中的功能。这些说明假设您正在使用 Bazel modules 来加载外部依赖项。如果您正在使用 Bazel 的旧版外部依赖项管理,我们建议您使用 Bazel's hybrid mode,然后按照本快速入门指南中的步骤操作。
此外,请查看 examples 以获取更多信息。
1. 启用 bzlmod
本仓库支持 bzlmod。
common --enable_bzlmod
2. 配置你的 MODULE.bazel 以使用 rules_swift_package_manager。
添加对 rules_swift_package_manager 的依赖。
bazel_dep(name = "rules_swift_package_manager", version = "1.23.0")
此外,添加以下内容以加载 Package.swift
和 Package.resolved 文件中描述的外部依赖项。
swift_deps = use_extension(
"@rules_swift_package_manager//:extensions.bzl",
"swift_deps",
)
swift_deps.from_package(
resolved = "//:Package.resolved",
swift = "//:Package.swift",
)
use_repo(
swift_deps,
"swift_deps_info", # This is generated by the ruleset.
# The name of the Swift package repositories will be added to this declaration in step 4 after
# running `bazel mod tidy`.
# NOTE: The name of the Bazel external repository for a Swift package is `swiftpkg_xxx` where
# `xxx` is the Swift package identity, lowercase, with punctuation replaced by `hyphen`. For
# example, the repository name for apple/swift-nio is `swiftpkg_swift_nio`.
)
您还需要添加对 rules_swift 的依赖。
注意:某些 Swift 包管理器功能(例如 resources)使用了 rules_apple 中的规则。它是 rules_swift_package_manager 的依赖项。但是,除非您在项目中使用其中任何规则,否则您无需声明它。
(可选)使用 swift_package 仓库来更新包
swift_deps 模块扩展默认会生成一个 swift_package 仓库,可用于执行 swift package 命令。
如果您希望控制 swift package 的标志和行为,或者根据 Bazel 配置的工具链使用正确的 swift 二进制文件,这将非常有用。
例如,要解析 Package.swift 文件:
bazel run @swift_package//:resolve
要将软件包更新到其最新支持的版本:
bazel run @swift_package//:update
两个目标都支持传递参数,因此,例如,你可以更新单个软件包:
bazel run @swift_package//:update -- MyPackage
这些目标将更新在 swift_deps.from_package 中定义的 Package.resolved 文件。
这些目标默认应用了旨在实现最佳 Bazel 兼容性的标志,如果您希望进一步配置,可以使用 configure_swift_package:
# MODULE.bazel
swift_deps.configure_swift_package(
build_path = "spm-build",
cache_path = "spm-cache",
dependency_caching = "false",
manifest_cache = "none",
manifest_caching = "false",
)
如果您不想使用 swift_package 仓库,您可以在 swift_deps.from_package 调用中禁用它:
swift_deps.from_package(
declare_swift_package = False, # <=== Disable the `swift_package` repository
resolved = "//:Package.resolved",
swift = "//:Package.swift",
)
(可选)为 Gazelle 插件启用 swift_deps_info 生成
如果您将使用 Gazelle plugin for Swift,则需要通过启用 declare_swift_deps_info 来启用 swift_deps_info 仓库的生成。
swift_deps.from_package(
declare_swift_deps_info = True, # <=== Enable swift_deps_info generation for the Gazelle plugin
resolved = "//:Package.resolved",
swift = "//:Package.swift",
)
(可选)为生成的 Swift 包目标添加依赖项
如果生成的 Swift 包目标缺少 Bazel 依赖项,请使用 configure_package 为该生成的目标追加 deps。
swift_deps.configure_package(
name = "ExamplePackage",
target_deps = {
"ExampleTarget": [
":same_build_file_dep",
"@other_repo//:dep",
"@//app:main_repo_dep",
],
},
)
键通常应为不带 .rspm 的 Swift 包目标名称;这些名称映射到诸如 ExampleTarget.rspm.__impl 之类的生成实现目标。如果键已包含 .rspm,则将其作为生成目标名称原样匹配。
3. 创建一个最小的 Package.swift 文件。
创建一个仅包含 Bazel 工作区直接使用的外部依赖项的最小 Package.swift 文件。
// swift-tools-version: 5.7
import PackageDescription
let package = Package(
name: "my-project",
dependencies: [
// Replace these entries with your dependencies.
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.0"),
.package(url: "https://github.com/apple/swift-log", from: "1.4.4"),
]
)
包的名称可以是你喜欢的任何名称。它是清单所必需的,但不会被 rules_swift_package_manager 使用。如果你的项目已发布并作为 Swift 包使用,请随意填写清单的其余部分,以便你的包能由 Swift 包管理器正常工作。请注意,[Swift Gazelle 插件] 不使用清单来生成 Bazel 构建文件。
4. 运行 swift package update
这将调用 Swift Package Manager 并解析所有依赖项,从而生成
Package.resolved 文件。
5. 运行 bazel mod tidy。
这将使用正确的 use_repo 声明更新你的 MODULE.bazel。
6. 构建并测试你的项目。
构建并测试你的项目。
bazel test //...
7. 检查 Package.swift、Package.resolved 和 MODULE.bazel。
Package.swift文件由rules_swift_package_manager使用,用于生成有关 项目依赖项的信息。Package.resolved文件指定了已识别的 所下载依赖项的确切版本。MODULE.bazel包含外部依赖项的声明。
8. 开始编码
你已准备好开始编码。
使用 Swift 包注册表
技巧与窍门
在操作你的仓库时,请考虑以下几点:
- 你是否正在尝试使用一个 Swift 包,但它无法在 Bazel 下构建?如果你能找出 修复方法,你可以对该 Swift 包进行补丁。请参阅[我们关于修补 Swift 包的文档]。