Awesome
Swift Package Manager Rules for Bazel
swift_bazel
is now rules_swift_package_manager
2023-04-03: The swift_bazel
repository was renamed to
rules_swift_package_manager. The
successor to rules_spm
now supersedes the functionality in this repository. As a result, this
repository is being archived.
swift_bazel
is replacing rules_spm
2023-01-10: The swift_bazel project, the successor for
rules_spm
, is now ready for testing. In addition to managing external Swift package
dependencies, it also provides functionality for generating Bazel build files for your Swift
project. If you have used rules_spm
for your projects or if you are just looking for a way to
manage external Swift packages in your Bazel workspace, I encourage you to check out
swift_bazel and provide your feedback.
Important Message for iOS Developers
2022-11-28: There are some known issues
with building and deplying applications for iOS devices using rules_spm
. If you need to deploy to
an iOS device, we do not recommend using rules_spm
, at this time.
Work is currently underway to implement a Gazelle plugin that will resolve external package
dependencies and generate Bazel build files that will build the external packages using
rules_swift. This will allow applications to be built
and deployed to any platforms/devices supported by rules_swift
and rules_apple
. Information
about the plugin will be posted to here and bazelbuild.slack.com in
the coming weeks.
This repository contains rules for Bazel that can be used to download, build and consume Swift packages with rules_swift rules. The rules in this repository build the external Swift packages with Swift Package Manager, then make the outputs available to Bazel rules.
Table of Contents
Reference Documentation
Click here for reference documentation for the rules and other definitions in this repository.
Prerequisites
Mac OS
Be sure to install Xcode.
Linux
You will need to install Swift. Make sure
that running swift --version
works properly.
Don't forget that rules_swift
expects the use of
clang
. Hence,
you will need to specify CC=clang
before running Bazel.
In addition, the Bazel toolchains want to use the Gold
linker. While it may be installed on the system, it is
possible that it will not be findable when using clang
as mentioned previously. So, you will want
to do one of the following:
Option #1: Create a symlink to the linker in the clang
directory.
sudo ln -s $(which ld.gold) $(dirname $(which clang))
This option worked well on a fairly minimal install of Ubuntu 20.04.
Option #2: Specify a custom PATH
via --action_env
Specify a custom PATH
to Bazel via --action_env
. The custom PATH
should have the Swift bin
directory as the first item.
swift_exec=$(which swift)
real_swift_exec=$(realpath $swift_exec)
real_swift_dir=$(dirname $real_swift_exec)
new_path="${real_swift_dir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
cat >>local.bazelrc <<EOF
build --action_env=PATH=${new_path}
EOF
This approach was necessary to successfully execute the examples on an Ubuntu runner using Github actions. See the Github workflow for more details.
<a id="#quickstart"></a>
Quickstart
The following provides a quick introduction on how to use the rules in this repository. Also, check out the examples directory for more information.
1. Configure your workspace to use rules_spm
Add the following to your WORKSPACE
file to add this repository and its dependencies.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "cgrindel_rules_spm",
sha256 = "777e687245faa7340488e61f5abb23b95b4c0e27e05f7cea7318c03e4cc38289",
strip_prefix = "rules_spm-0.11.2",
urls = [
"http://github.com/cgrindel/rules_spm/archive/v0.11.2.tar.gz",
],
)
load(
"@cgrindel_rules_spm//spm:deps.bzl",
"spm_rules_dependencies",
)
spm_rules_dependencies()
load(
"@build_bazel_rules_swift//swift:repositories.bzl",
"swift_rules_dependencies",
)
swift_rules_dependencies()
load(
"@build_bazel_rules_swift//swift:extras.bzl",
"swift_rules_extra_dependencies",
)
swift_rules_extra_dependencies()
<!-- END WORKSPACE SNIPPET -->
2. Add external Swift packages as dependencies to your workspace
Add the following to download and build apple/swift-log to
your workspace. NOTE: It is imperative that the products that will be used by your project are
listed in the products
list.
load("@cgrindel_rules_spm//spm:defs.bzl", "spm_pkg", "spm_repositories")
spm_repositories(
name = "swift_pkgs",
dependencies = [
spm_pkg(
"https://github.com/apple/swift-log.git",
exact_version = "1.4.2",
products = ["Logging"],
),
],
)
3. Use the module(s) defined in the Swift packages
Each Swift package can contain multiple Swift modules. A Bazel target is created for each Swift
module which is exported by the products that were listed in the spm_pkg
declaration.
The following shows a Bazel BUILD file with a swift_binary
that depends upon the Logging
module
defined in apple/swift-log.
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_binary")
swift_binary(
name = "simple",
srcs = ["main.swift"],
visibility = ["//swift:__subpackages__"],
deps = [
"@swift_pkgs//swift-log:Logging",
],
)
Lastly, import the Swift module and enjoy!
import Logging
let logger = Logger(label: "com.example.main")
logger.info("Hello World!")