rules_spm
rules_spm copied to clipboard
Provide a means for integrating external Swift packages built by Swift Package Manager into Bazel build using rules_swift.
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
- Prerequisites
- Mac OS
- Linux
- Option #1: Create a symlink to the linker in the clang directory.
- Option #2: Specify a custom PATH via --action_env
- Quickstart
- 1. Configure your workspace to use rules_spm
- 2. Add external Swift packages as dependencies to your workspace
- 3. Use the module(s) defined in the Swift packages
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.
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()
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!")