Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 2 additions & 30 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,11 @@ x_defaults:
test_targets:
- "//examples/..."
- "//test/..."
linux_environment: &linux_environment
platform: ubuntu2204
environment:
SWIFT_VERSION: "6.0.3"
SWIFT_HOME: "$HOME/swift-$SWIFT_VERSION"
PATH: "$SWIFT_HOME/usr/bin:$PATH"
linux_common: &linux_common
<<: *linux_environment
build_flags: &linux_flags
# On Linux, we look for Swift toolchain binaries on the path. We may be
# able to change this when we start auto-downloading toolchains (see
# https://github.com/bazelbuild/rules_swift/issues/4).
- "--action_env=PATH"
platform: ubuntu2204
build_targets:
- "//examples/..."
- "-//examples/apple/..."
test_flags: *linux_flags
test_targets:
- "//examples/..."
- "//test/..."
Expand Down Expand Up @@ -73,28 +61,16 @@ tasks:
ubuntu2204_latest:
name: "Current LTS"
bazel: latest
shell_commands:
- "echo --- Downloading and extracting Swift $SWIFT_VERSION to $SWIFT_HOME"
- "mkdir $SWIFT_HOME"
- "curl https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2204/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz | tar xvz --strip-components=1 -C $SWIFT_HOME"
<<: *linux_common

ubuntu2204_rolling:
name: "Latest rolling"
bazel: rolling
shell_commands:
- "echo --- Downloading and extracting Swift $SWIFT_VERSION to $SWIFT_HOME"
- "mkdir $SWIFT_HOME"
- "curl https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2204/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz | tar xvz --strip-components=1 -C $SWIFT_HOME"
<<: *linux_common

ubuntu2204_last_green:
name: "Last Green Bazel"
bazel: last_green
shell_commands:
- "echo --- Downloading and extracting Swift $SWIFT_VERSION to $SWIFT_HOME"
- "mkdir $SWIFT_HOME"
- "curl https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2204/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz | tar xvz --strip-components=1 -C $SWIFT_HOME"
<<: *linux_common

# TODO: re-enable when Windows in Bazel CI is properly configured for Swift.
Expand All @@ -106,11 +82,7 @@ tasks:
doc_tests:
name: "Doc tests"
bazel: latest
<<: *linux_environment
shell_commands:
- "echo --- Downloading and extracting Swift $SWIFT_VERSION to $SWIFT_HOME"
- "mkdir $SWIFT_HOME"
- "curl https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2204/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz | tar xvz --strip-components=1 -C $SWIFT_HOME"
platform: ubuntu2204
test_targets:
- "doc/..."

Expand Down
12 changes: 1 addition & 11 deletions .bcr/presubmit.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,18 @@
shell_commands: &shell_commands
- "echo --- Downloading and extracting Swift $SWIFT_VERSION to $SWIFT_HOME"
- "mkdir $SWIFT_HOME"
- "curl https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2004/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu20.04.tar.gz | tar xvz --strip-components=1 -C $SWIFT_HOME"

matrix:
bazel:
- 8.x
- 9.x
- rolling
platform:
- ubuntu2004
- ubuntu2204
tasks:
verify_targets:
name: Verify build targets
bazel: ${{ bazel }}
platform: ${{ platform }}
environment:
CC: "clang"
SWIFT_VERSION: "6.0.3"
SWIFT_HOME: "$HOME/swift-$SWIFT_VERSION"
PATH: "$PATH:$SWIFT_HOME/usr/bin"
shell_commands: *shell_commands
build_flags:
- "--action_env=PATH"
- "--incompatible_enable_proto_toolchain_resolution"
build_targets:
- "@rules_swift//examples/xplatform/..."
Expand Down
14 changes: 14 additions & 0 deletions .github/generate-notes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,19 @@ This release is compatible with: TODO

\`\`\`bzl
bazel_dep(name = "rules_swift", version = "$new_version")

swift = use_extension(
"@rules_swift//swift:extensions.bzl",
"swift",
)
swift.toolchain(
name = "swift_toolchain",
# Use "ubuntu22.04" or another supported platform on Linux.
platforms = ["xcode"],
swift_version = "6.3",
)
use_repo(swift, "swift_toolchain")

register_toolchains("@swift_toolchain//:all")
\`\`\`
EOF
23 changes: 6 additions & 17 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,11 @@ use_repo(
"com_github_grpc_grpc_swift",
"rules_swift_index_import_5_8",
"rules_swift_index_import_6_1",
"rules_swift_local_config",
)

apple_cc_configure = use_extension("@apple_support//crosstool:setup.bzl", "apple_cc_configure_extension")
use_repo(apple_cc_configure, "local_config_apple_cc")

register_toolchains("//swift/toolchains:all")

system_sdk = use_extension("//swift:extensions.bzl", "system_sdk")
system_sdk.configure_sdks(
# NOTE: This doesn't apply to downstream repos
Expand Down Expand Up @@ -82,6 +79,11 @@ use_repo(system_sdk, "system_sdk")
swift = use_extension("//swift:extensions.bzl", "swift", dev_dependency = True)
swift.toolchain(
name = "swift_toolchain",
platforms = [
"ubuntu22.04",
"ubuntu22.04-aarch64",
"xcode",
],
swift_version = "6.3",
)
use_repo(
Expand All @@ -93,20 +95,7 @@ use_repo(
)

register_toolchains(
# We're using ubuntu22.04 here because that's what's used in the current rules_swift buildkite CI.
# In a perfect world, we would be able to have bazel automatically use the toolchain that just works.
# Unfortunately, we are not in this world yet. This would require either one of these two things to happen:
# * either have a constraint to select on the current distribution, which would allow us to register all
# the toolchains and have bazel automatically select the right one. But there is no such constraint today.
# * or have a swift universal Linux toolchain. Which is not the case today.
# Anyway, for now we will need to update this every time we update the CI environment. Contributors might also
# have to update this list if they're testing on a different Linux distribution.
"@swift_toolchain//:cc_toolchain_embedded_ubuntu22.04",
"@swift_toolchain//:cc_toolchain_embedded_ubuntu22.04-aarch64",
"@swift_toolchain//:cc_toolchain_embedded_xcode",
"@swift_toolchain//:swift_toolchain_embedded_ubuntu22.04",
"@swift_toolchain//:swift_toolchain_embedded_ubuntu22.04-aarch64",
"@swift_toolchain//:swift_toolchain_embedded_xcode",
"@swift_toolchain//:all",
dev_dependency = True,
)

Expand Down
64 changes: 20 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ If you run into any problems with these rules, please

## Basic Examples

Create a simple CLI that can run on macOS, Linux, or Windows:
Create a simple CLI that can run on macOS or Linux:

```bzl
load("@rules_swift//swift:swift_binary.bzl", "swift_binary")
Expand Down Expand Up @@ -46,64 +46,40 @@ repository.

## Quick Setup

### 1. Install Swift
### 1. Configure your workspace

Before getting started, make sure that you have a Swift toolchain installed.
Copy the `MODULE.bazel` snippet from
[the releases page](https://github.com/bazelbuild/rules_swift/releases), then
select the platform that matches your build host. `rules_swift` downloads the
selected Swift release and registers it as a hermetic Bazel toolchain; it does
not discover or use a Swift installation from the host.

**Apple users:** Install [Xcode](https://developer.apple.com/xcode/downloads/).
If this is your first time installing it, make sure to open it once after
installing so that the command line tools are correctly configured.
See [Hermetic Swift toolchain](doc/standalone_toolchain.md) for the complete
setup and the supported platform names.

**Linux users:** Follow the instructions on the
[Swift download page](https://swift.org/download/) to download and install the
appropriate Swift toolchain for your platform. Take care to ensure that you have
all of Swift's dependencies installed (such as ICU, Clang, and so forth), and
also ensure that the Swift compiler is available on your system path.
### 2. Install platform dependencies

### 2. Configure your workspace
**Apple users:** Install [Xcode](https://developer.apple.com/xcode/downloads/).
`rules_swift` uses the Xcode SDKs and Apple linker, but Swift compiler actions
use the hermetic toolchain declared in `MODULE.bazel`. If this is your first
time installing Xcode, open it once so that the command line tools are
configured.

Copy the `MODULE.bazel` snippet from [the releases page](https://github.com/bazelbuild/rules_swift/releases).
**Linux users:** Install the system dependencies required by the selected
swift.org toolchain, including Clang and ICU.

### 3. Additional configuration (Linux only)
### 3. Configure Clang (Linux only)

The `swift_binary` and `swift_test` rules expect to use `clang` as the driver
for linking, and they query the Bazel C++ API and CROSSTOOL to determine which
arguments should be passed to the linker. By default, the C++ toolchain used by
Bazel is `gcc`, so Swift users on Linux need to override this by setting the
environment variable `CC=clang` when invoking Bazel.
environment variable `CC=clang` when invoking Bazel. The downloaded Swift
toolchain does not replace Bazel's C++ toolchain.

This step is not necessary for macOS users because the Xcode toolchain always
uses `clang`.

## Building with a Standalone Swift Toolchain

As an alternative to the host's Swift install, `rules_swift` can download
and register a hermetic Swift toolchain from swift.org. See
[doc/standalone_toolchain.md](doc/standalone_toolchain.md) for setup
instructions.

## Building with Custom Toolchains

**macOS hosts:** You can build with a custom Swift toolchain (downloaded
from https://swift.org/download) instead of Xcode's default. To do so,
pass the following flag to Bazel:

```lang-none
--action_env=TOOLCHAINS=toolchain.id
```

Where `toolchain.id` is the value of the `CFBundleIdentifier` key in the
toolchain's Info.plist file.

To list the available toolchains and their bundle identifiers, you can run:

```command
bazel run @rules_swift//tools/dump_toolchains
```

**Linux hosts:** At this time, Bazel uses whichever `swift` executable is
encountered first on your `PATH`.

## Supporting debugging

To make cacheable builds work correctly with debugging see
Expand Down
4 changes: 3 additions & 1 deletion doc/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ that use the toolchain.
## SwiftToolsInfo

<pre>
SwiftToolsInfo(<a href="#SwiftToolsInfo-swift_driver">swift_driver</a>, <a href="#SwiftToolsInfo-swift_autolink_extract">swift_autolink_extract</a>, <a href="#SwiftToolsInfo-swift_symbolgraph_extract">swift_symbolgraph_extract</a>, <a href="#SwiftToolsInfo-additional_inputs">additional_inputs</a>)
SwiftToolsInfo(<a href="#SwiftToolsInfo-swift_driver">swift_driver</a>, <a href="#SwiftToolsInfo-swift_autolink_extract">swift_autolink_extract</a>, <a href="#SwiftToolsInfo-swift_symbolgraph_extract">swift_symbolgraph_extract</a>,
<a href="#SwiftToolsInfo-swift_synthesize_interface">swift_synthesize_interface</a>, <a href="#SwiftToolsInfo-additional_inputs">additional_inputs</a>)
</pre>

Propagates information about Swift toolchain tools that can be specified as
Expand All @@ -326,6 +327,7 @@ dependencies, ensuring they are available in the execution environment.
| <a id="SwiftToolsInfo-swift_driver"></a>swift_driver | `File`. The Swift driver executable that orchestrates compilation and linking operations. This is the main entry point for invoking the Swift compiler toolchain. |
| <a id="SwiftToolsInfo-swift_autolink_extract"></a>swift_autolink_extract | `File`. The executable that extracts autolink information from object files. This tool is used to determine which libraries need to be linked based on import statements in Swift code. |
| <a id="SwiftToolsInfo-swift_symbolgraph_extract"></a>swift_symbolgraph_extract | `File`. The executable that extracts symbol graph information from Swift modules. This tool generates structured data about APIs, which can be used for documentation generation and other tooling purposes. |
| <a id="SwiftToolsInfo-swift_synthesize_interface"></a>swift_synthesize_interface | `File` or `None`. The executable that synthesizes Swift interfaces. |
| <a id="SwiftToolsInfo-additional_inputs"></a>additional_inputs | `List` of `File`s. Additional files to add to the action input root when calling these tools. |


Expand Down
67 changes: 28 additions & 39 deletions doc/standalone_toolchain.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Standalone Swift toolchain
# Hermetic Swift toolchain

`rules_swift` ships a Bzlmod module extension that downloads a standalone
Swift toolchain from [swift.org](https://swift.org/download) and registers
it with Bazel. This gives you a hermetic Swift toolchain that does not rely
on the host's pre-installed compiler (or Xcode), which is useful for
reproducible builds, CI, and cross-platform builds.
`rules_swift` uses a Bzlmod module extension to download a Swift toolchain from
[swift.org](https://swift.org/download) and expose it to Bazel toolchain
resolution. `rules_swift` does not discover a Swift compiler from `PATH`, Xcode,
or the Windows host. Every build must declare and register a hermetic Swift
toolchain in the root `MODULE.bazel`.

The extension supports both macOS (`.pkg`) and Linux (`.tar.gz`) toolchain
archives.
The extension supports macOS (`.pkg`) and Linux (`.tar.gz`) toolchain archives.
Apple builds still use the SDKs, Clang, and linker from Xcode, but all Swift
compiler actions use the downloaded Swift toolchain.

## Quick start

Expand All @@ -21,37 +22,27 @@ swift = use_extension(

swift.toolchain(
name = "swift_toolchain",
swift_version = "6.2.4",
platforms = ["xcode"],
swift_version = "6.3",
)

use_repo(
swift,
"swift_toolchain",
# Add one entry per platform you intend to build on. The repo names are
# of the form `<name>_<platform>`.
"swift_toolchain_xcode",
"swift_toolchain_ubuntu22.04",
"swift_toolchain_ubuntu22.04-aarch64",
)
use_repo(swift, "swift_toolchain")

register_toolchains(
"@swift_toolchain//:cc_toolchain_embedded_xcode",
"@swift_toolchain//:swift_toolchain_embedded_xcode",
"@swift_toolchain//:cc_toolchain_embedded_ubuntu22.04",
"@swift_toolchain//:swift_toolchain_embedded_ubuntu22.04",
"@swift_toolchain//:cc_toolchain_embedded_ubuntu22.04-aarch64",
"@swift_toolchain//:swift_toolchain_embedded_ubuntu22.04-aarch64",
)
register_toolchains("@swift_toolchain//:all")
```

You only need to `use_repo` and `register_toolchains` for the platforms you
actually build on. Each platform repo name is `<toolchain_name>_<platform>`.
This example configures a macOS build host. For Ubuntu 22.04 on x86-64, use
`platforms = ["ubuntu22.04"]`; for Ubuntu 22.04 on Arm64, use
`platforms = ["ubuntu22.04-aarch64"]`. List every build-host platform used by
developers and CI. The generated `@swift_toolchain//:all` target pattern
contains only the selected platforms.

## The `swift.toolchain` tag

| Attribute | Type | Description |
|---|---|---|
| `name` | string, required | Repository name of the generated parent toolchain repo. Per-platform repos are named `<name>_<platform>`. |
| `platforms` | string_list | Platform archives to download and generate toolchain declarations for. Defaults to every platform available for the selected Swift version. Explicit selection is recommended. |
| `swift_version` | string | The Swift release version (e.g. `6.2.4`) or a snapshot identifier (see [Snapshots](#snapshot-toolchains)). Mutually exclusive with `swift_version_file`. |
| `swift_version_file` | label | A label pointing at a file containing the version string (typically a `.swift-version` file checked into the repo). Mutually exclusive with `swift_version`. |
| `platform_sha256` | string_dict | Optional map of platform → SHA-256. Required for snapshots and any version not present in the bundled `SWIFT_RELEASES` table. When set, it overrides the bundled checksums. |
Expand All @@ -69,8 +60,8 @@ The platform keys come from the swift.org download URLs and currently include:
* `ubi9`, `ubi9-aarch64`

Bazel does not currently have constraints to auto-select between Linux
distributions, so you must explicitly `register_toolchains` for the
distribution(s) your CI and developers run on.
distributions, so `platforms` must identify the distribution(s) that CI and
developers run on.

The macOS (`xcode`) archive is a `.pkg` and can only be extracted on a
macOS host — pulling it on Linux will fail at fetch time.
Expand All @@ -83,8 +74,9 @@ For each platform, the parent repo (`@<name>`) exposes:
Swift target platform.
* `swift_toolchain_embedded_<platform>` — Swift toolchain for the embedded
target.
* `swift_toolchain_exec_<platform>` — Swift toolchain for use as an exec
toolchain (i.e. compiling tools that run on the build host).
* `swift_toolchain_exec_<platform>` — Swift toolchain for Linux host targets.
* `xcode-toolchain-*` and `xcode-sdk-toolchain-*` — Swift toolchains for Apple
target platforms, generated when `platforms` contains `xcode`.

The per-platform repo (`@<name>_<platform>`) holds the extracted Swift
toolchain itself and is what the toolchain targets above point at.
Expand Down Expand Up @@ -161,12 +153,9 @@ swift = use_extension(
)
```

## Building with the standalone toolchain
## Building with the hermetic toolchain

Once registered, normal `swift_binary`, `swift_library`, and `swift_test`
targets pick up the toolchain through Bazel's standard toolchain
resolution — no per-target configuration is needed.

This is independent of the macOS `--action_env=TOOLCHAINS=…` mechanism
described in the top-level README, which selects between Xcode-managed
toolchains rather than between hermetic Bazel-managed ones.
targets pick up the toolchain through Bazel's standard toolchain resolution;
no per-target configuration is needed. `PATH`, `TOOLCHAINS`, and an Xcode Swift
compiler do not select or replace the registered hermetic Swift compiler.
Loading
Loading