BUILD rules to define Swift libraries and executable binaries.
This file is the public interface that users should import to use the Swift
rules. Do not import definitions from the internal
subdirectory directly.
To use the Swift build rules in your BUILD files, load them from
@build_bazel_rules_swift//swift:swift.bzl
.
For example:
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
Rules
swift_binary
Compiles and links Swift code into an executable binary.
On Linux, this rule produces an executable binary for the desired target architecture.
On Apple platforms, this rule produces a single-architecture binary; it does not produce fat binaries. As such, this rule is mainly useful for creating Swift tools intended to run on the local build machine.
If you want to create a multi-architecture binary or a bundled application,
please use one of the platform-specific application rules in
rules_apple instead of
swift_binary
.
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_binary")
swift_binary(
# A unique name for this target.
name = "",
)
name
A unique name for this target.
copts
Additional compiler options that should be passed to swiftc
. These strings are
subject to $(location ...)
and "Make" variable expansion.
data
The list of files needed by this target at runtime.
Files and targets named in the data
attribute will appear in the *.runfiles
area of this target, if it has one. This may include data files needed by a
binary or library, or other programs needed by it.
defines
A list of defines to add to the compilation command line.
Note that unlike C-family languages, Swift defines do not have values; they are
simply identifiers that are either defined or undefined. So strings in this list
should be simple identifiers, not name=value
pairs.
Each string is prepended with -D
and added to the command line. Unlike
copts
, these flags are added for the target and every target that depends on
it, so use this attribute with caution. It is preferred that you add defines
directly to copts
, only using this feature in the rare case that a library
needs to propagate a symbol up to those that depend on it.
deps
A list of targets that are dependencies of the target being built, which will be linked into that target.
If the Swift toolchain supports implementation-only imports (private_deps
on
swift_library
), then targets in deps
are treated as regular
(non-implementation-only) imports that are propagated both to their direct and
indirect (transitive) dependents.
Allowed kinds of dependencies are:
swift_c_module
,swift_import
andswift_library
(or anything propagatingSwiftInfo
)cc_library
(or anything propagatingCcInfo
)
Additionally, on platforms that support Objective-C interop, objc_library
targets (or anything propagating the apple_common.Objc
provider) are allowed
as dependencies. On platforms that do not support Objective-C interop (such as
Linux), those dependencies will be ignored.
linkopts
Additional linker options that should be passed to clang
. These strings are
subject to $(location ...)
expansion.
malloc
Override the default dependency on malloc
.
By default, Swift binaries are linked against @bazel_tools//tools/cpp:malloc"
,
which is an empty library and the resulting binary will use libc's malloc
.
This label must refer to a cc_library
rule.
module_name
The name of the Swift module being built.
If left unspecified, the module name will be computed based on the target's
build label, by stripping the leading //
and replacing /
, :
, and other
non-identifier characters with underscores.
srcs
A list of .swift
source files that will be compiled into the library.
stamp
Enable or disable link stamping; that is, whether to encode build information into the binary. Possible values are:
stamp = 1
: Stamp the build information into the binary. Stamped binaries are only rebuilt when their dependencies change. Use this if there are tests that depend on the build information.stamp = 0
: Always replace build information by constant values. This gives good build result caching.stamp = -1
: Embedding of build information is controlled by the--[no]stamp
flag.
swiftc_inputs
Additional files that are referenced using $(location ...)
in attributes that
support location expansion.
swift_c_module
Wraps one or more C targets in a new module map that allows it to be imported into Swift to access its C interfaces.
The cc_library
rule in Bazel does not produce module maps that are compatible
with Swift. In order to make interop between Swift and C possible, users have
one of two options:
Use an auto-generated module map. In this case, the
swift_c_module
rule is not needed. If acc_library
is a direct dependency of aswift_{binary,library,test}
target, a module map will be automatically generated for it and the module's name will be derived from the Bazel target label (in the same fashion that module names for Swift targets are derived). The module name can be overridden by setting theswift_module
tag on thecc_library
; e.g.,tags = ["swift_module=MyModule"]
.Use a custom module map. For finer control over the headers that are exported by the module, use the
swift_c_module
rule to provide a custom module map that specifies the name of the module, its headers, and any other module information. Thecc_library
targets that contain the headers that you wish to expose to Swift should be listed in thedeps
of yourswift_c_module
(and by listing multiple targets, you can export multiple libraries under a single module if desired). Then, yourswift_{binary,library,test}
targets should depend on theswift_c_module
target, not on the underlyingcc_library
target(s).
NOTE: Swift at this time does not support interop directly with C++. Any headers
referenced by a module map that is imported into Swift must have only C features
visible, often by using preprocessor conditions like #if __cplusplus
to hide
any C++ declarations.
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_c_module")
swift_c_module(
# A unique name for this target.
name = "",
# A list of C targets (or anything propagating `CcInfo`) that are dependencies of
deps = [],
# The module map file that should be loaded to import the C library dependency
module_map = "",
# The name of the top-level module in the module map that this target represents
module_name = "",
)
name
A unique name for this target.
deps
A list of C targets (or anything propagating CcInfo
) that are dependencies of
this target and whose headers may be referenced by the module map.
module_map
The module map file that should be loaded to import the C library dependency into Swift.
module_name
The name of the top-level module in the module map that this target represents.
A single module.modulemap
file can define multiple top-level modules. When
building with implicit modules, the presence of that module map allows any of
the modules defined in it to be imported. When building explicit modules,
however, there is a one-to-one correspondence between top-level modules and
BUILD targets and the module name must be known without reading the module map
file, so it must be provided directly. Therefore, one may have multiple
swift_c_module
targets that reference the same module.modulemap
file but
with different module names and headers.
swift_feature_allowlist
Limits the ability to request or disable certain features to a set of packages (and possibly subpackages) in the workspace.
A Swift toolchain target can reference any number (zero or more) of
swift_feature_allowlist
targets. The features managed by these allowlists may
overlap. For some package P, a feature is allowed to be used by targets in
that package if P matches the packages
patterns in all of the allowlists
that manage that feature.
A feature that is not managed by any allowlist is allowed to be used by any package.
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_feature_allowlist")
swift_feature_allowlist(
# A unique name for this target.
name = "",
# A list of strings representing packages (possibly recursive) whose targets are
packages = [],
)
name
A unique name for this target.
managed_features
A list of feature strings that are permitted to be specified by the targets in
the packages matched by the packages
attribute. This list may include both
feature names and/or negations (a name with a leading -
); a regular feature
name means that the targets in the matching packages may explicitly request that
the feature be enabled, and a negated feature means that the target may
explicitly request that the feature be disabled.
For example, managed_features = ["foo", "-bar"]
means that targets in the
allowlist's packages may request that feature "foo"
be enabled and that
feature "bar"
be disabled.
packages
A list of strings representing packages (possibly recursive) whose targets are
allowed to enable/disable the features in managed_features
. Each package
pattern is written in the syntax used by the package_group
function:
-
//foo/bar
: Targets in the package//foo/bar
but not in subpackages. //foo/bar/...
: Targets in the package//foo/bar
and any of its subpackages.- A leading
-
excludes packages that would otherwise have been included by the patterns in the list.
Exclusions always take priority over inclusions; order in the list is irrelevant.
swift_grpc_library
Generates a Swift library from gRPC services defined in protocol buffer sources.
There should be one swift_grpc_library
for any proto_library
that defines
services. A target based on this rule can be used as a dependency anywhere that
a swift_library
can be used.
We recommend that swift_grpc_library
targets be located in the same package as
the proto_library
and swift_proto_library
targets they depend on. For more
best practices around the use of Swift protocol buffer build rules, see the
documentation for swift_proto_library
.
Defining Build Targets for Services
Note that swift_grpc_library
only generates the gRPC service interfaces (the
service
definitions) from the .proto
files. Any messages defined in the same
.proto
file must be generated using a swift_proto_library
target. Thus, the
typical structure of a Swift gRPC library is similar to the following:
proto_library(
name = "my_protos",
srcs = ["my_protos.proto"],
)
# Generate Swift types from the protos.
swift_proto_library(
name = "my_protos_swift",
deps = [":my_protos"],
)
# Generate Swift types from the services.
swift_grpc_library(
name = "my_protos_client_services_swift",
# The `srcs` attribute points to the `proto_library` containing the service
# definitions...
srcs = [":my_protos"],
# ...the `flavor` attribute specifies the kind of definitions to generate...
flavor = "client",
# ...and the `deps` attribute points to the `swift_proto_library` that was
# generated from the same `proto_library` and which contains the messages
# used by those services.
deps = [":my_protos_swift"],
)
# Generate test stubs from swift services.
swift_grpc_library(
name = "my_protos_client_stubs_swift",
# The `srcs` attribute points to the `proto_library` containing the service
# definitions...
srcs = [":my_protos"],
# ...the `flavor` attribute specifies the kind of definitions to generate...
flavor = "client_stubs",
# ...and the `deps` attribute points to the `swift_grpc_library` that was
# generated from the same `proto_library` and which contains the service
# implementation.
deps = [":my_protos_client_services_swift"],
)
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_grpc_library")
swift_grpc_library(
# A unique name for this target.
name = "",
# The kind of definitions that should be generated:
flavor = "",
)
name
A unique name for this target.
deps
Exactly one swift_proto_library
or swift_grpc_library
target that contains
the Swift protos used by the services being generated. Test stubs should depend
on the swift_grpc_library
implementing the service.
flavor
The kind of definitions that should be generated:
"client"
to generate client definitions."client_stubs"
to generate client test stubs."server"
to generate server definitions.
srcs
Exactly one proto_library
target that defines the services being generated.
swift_import
Allows for the use of precompiled Swift modules as dependencies in other
swift_library
and swift_binary
targets.
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_import")
swift_import(
# A unique name for this target.
name = "",
# The list of `.a` files provided to Swift targets that depend on this target
archives = [],
# The name of the module represented by this target.
module_name = "",
# The `.swiftmodule` file provided to Swift targets that depend on this target
swiftmodule = "",
)
name
A unique name for this target.
archives
The list of .a
files provided to Swift targets that depend on this target.
data
The list of files needed by this target at runtime.
Files and targets named in the data
attribute will appear in the *.runfiles
area of this target, if it has one. This may include data files needed by a
binary or library, or other programs needed by it.
deps
A list of targets that are dependencies of the target being built, which will be linked into that target.
If the Swift toolchain supports implementation-only imports (private_deps
on
swift_library
), then targets in deps
are treated as regular
(non-implementation-only) imports that are propagated both to their direct and
indirect (transitive) dependents.
Allowed kinds of dependencies are:
swift_c_module
,swift_import
andswift_library
(or anything propagatingSwiftInfo
)cc_library
(or anything propagatingCcInfo
)
Additionally, on platforms that support Objective-C interop, objc_library
targets (or anything propagating the apple_common.Objc
provider) are allowed
as dependencies. On platforms that do not support Objective-C interop (such as
Linux), those dependencies will be ignored.
module_name
The name of the module represented by this target.
swiftdoc
The .swiftdoc
file provided to Swift targets that depend on this target.
swiftmodule
The .swiftmodule
file provided to Swift targets that depend on this target.
swift_library
Compiles and links Swift code into a static library and Swift module.
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_library")
swift_library(
# A unique name for this target.
name = "",
# A list of `.swift` source files that will be compiled into the library
srcs = [],
)
name
A unique name for this target.
alwayslink
If true, any binary that depends (directly or indirectly) on this Swift module
will link in all the object files for the files listed in srcs
, even if some
contain no symbols referenced by the binary. This is useful if your code isn't
explicitly called by code in the binary; for example, if you rely on runtime
checks for protocol conformances added in extensions in the library but do not
directly reference any other symbols in the object file that adds that
conformance.
copts
Additional compiler options that should be passed to swiftc
. These strings are
subject to $(location ...)
and "Make" variable expansion.
data
The list of files needed by this target at runtime.
Files and targets named in the data
attribute will appear in the *.runfiles
area of this target, if it has one. This may include data files needed by a
binary or library, or other programs needed by it.
defines
A list of defines to add to the compilation command line.
Note that unlike C-family languages, Swift defines do not have values; they are
simply identifiers that are either defined or undefined. So strings in this list
should be simple identifiers, not name=value
pairs.
Each string is prepended with -D
and added to the command line. Unlike
copts
, these flags are added for the target and every target that depends on
it, so use this attribute with caution. It is preferred that you add defines
directly to copts
, only using this feature in the rare case that a library
needs to propagate a symbol up to those that depend on it.
deps
A list of targets that are dependencies of the target being built, which will be linked into that target.
If the Swift toolchain supports implementation-only imports (private_deps
on
swift_library
), then targets in deps
are treated as regular
(non-implementation-only) imports that are propagated both to their direct and
indirect (transitive) dependents.
Allowed kinds of dependencies are:
swift_c_module
,swift_import
andswift_library
(or anything propagatingSwiftInfo
)cc_library
(or anything propagatingCcInfo
)
Additionally, on platforms that support Objective-C interop, objc_library
targets (or anything propagating the apple_common.Objc
provider) are allowed
as dependencies. On platforms that do not support Objective-C interop (such as
Linux), those dependencies will be ignored.
generated_header_name
The name of the generated Objective-C interface header. This name must end with
a .h
extension and cannot contain any path separators.
If this attribute is not specified, then the default behavior is to name the
header ${target_name}-Swift.h
.
This attribute is ignored if the toolchain does not support generating headers.
generates_header
If True, an Objective-C header will be generated for this target, in the same
build package where the target is defined. By default, the name of the header is
${target_name}-Swift.h
; this can be changed using the generated_header_name
attribute.
Targets should only set this attribute to True if they export Objective-C APIs. A header generated for a target that does not export Objective-C APIs will be effectively empty (except for a large amount of prologue and epilogue code) and this is generally wasteful because the extra file needs to be propagated in the build graph and, when explicit modules are enabled, extra actions must be executed to compile the Objective-C module for the generated header.
linkopts
Additional linker options that should be passed to the linker for the binary
that depends on this target. These strings are subject to $(location ...)
and "Make" variable expansion.
module_name
The name of the Swift module being built.
If left unspecified, the module name will be computed based on the target's
build label, by stripping the leading //
and replacing /
, :
, and other
non-identifier characters with underscores.
private_deps
A list of targets that are implementation-only dependencies of the target being built. Libraries/linker flags from these dependencies will be propagated to dependent for linking, but artifacts/flags required for compilation (such as .swiftmodule files, C headers, and search paths) will not be propagated.
Allowed kinds of dependencies are:
swift_c_module
,swift_import
andswift_library
(or anything propagatingSwiftInfo
)cc_library
(or anything propagatingCcInfo
)
Additionally, on platforms that support Objective-C interop, objc_library
targets (or anything propagating the apple_common.Objc
provider) are allowed
as dependencies. On platforms that do not support Objective-C interop (such as
Linux), those dependencies will be ignored.
srcs
A list of .swift
source files that will be compiled into the library.
swiftc_inputs
Additional files that are referenced using $(location ...)
in attributes that
support location expansion.
swift_module_alias
Creates a Swift module that re-exports other modules.
This rule effectively creates an "alias" for one or more modules such that a client can import the alias module and it will implicitly import those dependencies. It should be used primarily as a way to migrate users when a module name is being changed. An alias that depends on more than one module can be used to split a large module into smaller, more targeted modules.
Symbols in the original modules can be accessed through either the original module name or the alias module name, so callers can be migrated separately after moving the physical build target as needed. (An exception to this is runtime type metadata, which only encodes the module name of the type where the symbol is defined; it is not repeated by the alias module.)
Caution: This rule uses the undocumented
@_exported
feature to re-export thedeps
in the new module. You depend on undocumented features at your own risk, as they may change in a future version of Swift.
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_module_alias")
swift_module_alias(
# A unique name for this target.
name = "",
)
name
A unique name for this target.
deps
A list of targets that are dependencies of the target being built, which will be
linked into that target. Allowed kinds are swift_import
and swift_library
(or anything else propagating SwiftInfo
).
module_name
The name of the Swift module being built.
If left unspecified, the module name will be computed based on the target's
build label, by stripping the leading //
and replacing /
, :
, and other
non-identifier characters with underscores.
swift_proto_library
Generates a Swift library from protocol buffer sources.
There should be one swift_proto_library
for any proto_library
that you wish
to depend on. A target based on this rule can be used as a dependency anywhere
that a swift_library
can be used.
A swift_proto_library
target only creates a Swift module if the
proto_library
on which it depends has a non-empty srcs
attribute. If the
proto_library
does not contain srcs
, then no module is produced, but the
swift_proto_library
still propagates the modules of its non-empty dependencies
so that those generated protos can be used by depending on the
swift_proto_library
of the "collector" target.
Note that the module name of the Swift library produced by this rule (if any) is
based on the name of the proto_library
target, not the name of the
swift_proto_library
target. In other words, if the following BUILD file were
located in //my/pkg
, the target would create a Swift module named
my_pkg_foo
:
proto_library(
name = "foo",
srcs = ["foo.proto"],
)
swift_proto_library(
name = "foo_swift",
deps = [":foo"],
)
Because the Swift modules are generated from an aspect that is applied to the
proto_library
targets, the module name and other compilation flags for the
resulting Swift modules cannot be changed.
Tip: Where to locate swift_proto_library
targets
Convention is to put the swift_proto_library
in the same BUILD
file as the
proto_library
it is generating for (just like all the other
LANG_proto_library
rules). This lets anyone needing the protos in Swift share
the single rule as well as making it easier to realize what proto files are in
use in what contexts.
This is not a requirement, however, as it may not be possible for Bazel
workspaces that create swift_proto_library
targets that depend on
proto_library
targets from different repositories.
Tip: Avoid import
only .proto
files
Avoid creating a .proto
file that just contains import
directives of all the
other .proto
files you need. While this does group the protos into this new
target, it comes with some high costs. This causes the proto compiler to parse
all those files and invoke the generator for an otherwise empty source file.
That empty source file then has to get compiled, but it will have dependencies
on the full deps chain of the imports (recursively). The Swift compiler must
load all of these module dependencies, which can be fairly slow if there are
many of them, so this method of grouping via a .proto
file actually ends up
creating build steps that slow down the build.
Tip: Resolving unused import warnings
If you see warnings like the following during your build:
path/file.proto: warning: Import other/path/file.proto but not used.
The proto compiler is letting you know that you have an import
statement
loading a file from which nothing is used, so it is wasted work. The import
can be removed (in this case, import other/path/file.proto
could be removed
from path/file.proto
). These warnings can also mean that the proto_library
has deps
that aren't needed. Removing those along with the import
statement(s) will speed up downstream Swift compilation actions, because it
prevents unused modules from being loaded by swiftc
.
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_proto_library")
swift_proto_library(
# A unique name for this target.
name = "",
)
name
A unique name for this target.
deps
Exactly one proto_library
target (or any target that propagates a proto
provider) from which the Swift library should be generated.
swift_test
Compiles and links Swift code into an executable test target.
The behavior of swift_test
differs slightly for macOS targets, in order to
provide seamless integration with Apple's XCTest framework. The output of the
rule is still a binary, but one whose Mach-O type is MH_BUNDLE
(a loadable
bundle). Thus, the binary cannot be launched directly. Instead, running
bazel test
on the target will launch a test runner script that copies it into
an .xctest
bundle directory and then launches the xctest
helper tool from
Xcode, which uses Objective-C runtime reflection to locate the tests.
On Linux, the output of a swift_test
is a standard executable binary, because
the implementation of XCTest on that platform currently requires authors to
explicitly list the tests that are present and run them from their main program.
Test bundling on macOS can be disabled on a per-target basis, if desired. You
may wish to do this if you are not using XCTest, but rather a different test
framework (or no framework at all) where the pass/fail outcome is represented as
a zero/non-zero exit code (as is the case with other Bazel test rules like
cc_test
). To do so, disable the "swift.bundled_xctests"
feature on the
target:
swift_test(
name = "MyTests",
srcs = [...],
features = ["-swift.bundled_xctests"],
)
You can also disable this feature for all the tests in a package by applying it
to your BUILD file's package()
declaration instead of the individual targets.
Example usage (generated)
load("@rules_swift//swift:swift.bzl", "swift_test")
swift_test(
# A unique name for this target.
name = "",
)
name
A unique name for this target.
copts
Additional compiler options that should be passed to swiftc
. These strings are
subject to $(location ...)
and "Make" variable expansion.
data
The list of files needed by this target at runtime.
Files and targets named in the data
attribute will appear in the *.runfiles
area of this target, if it has one. This may include data files needed by a
binary or library, or other programs needed by it.
defines
A list of defines to add to the compilation command line.
Note that unlike C-family languages, Swift defines do not have values; they are
simply identifiers that are either defined or undefined. So strings in this list
should be simple identifiers, not name=value
pairs.
Each string is prepended with -D
and added to the command line. Unlike
copts
, these flags are added for the target and every target that depends on
it, so use this attribute with caution. It is preferred that you add defines
directly to copts
, only using this feature in the rare case that a library
needs to propagate a symbol up to those that depend on it.
deps
A list of targets that are dependencies of the target being built, which will be linked into that target.
If the Swift toolchain supports implementation-only imports (private_deps
on
swift_library
), then targets in deps
are treated as regular
(non-implementation-only) imports that are propagated both to their direct and
indirect (transitive) dependents.
Allowed kinds of dependencies are:
swift_c_module
,swift_import
andswift_library
(or anything propagatingSwiftInfo
)cc_library
(or anything propagatingCcInfo
)
Additionally, on platforms that support Objective-C interop, objc_library
targets (or anything propagating the apple_common.Objc
provider) are allowed
as dependencies. On platforms that do not support Objective-C interop (such as
Linux), those dependencies will be ignored.
linkopts
Additional linker options that should be passed to clang
. These strings are
subject to $(location ...)
expansion.
malloc
Override the default dependency on malloc
.
By default, Swift binaries are linked against @bazel_tools//tools/cpp:malloc"
,
which is an empty library and the resulting binary will use libc's malloc
.
This label must refer to a cc_library
rule.
module_name
The name of the Swift module being built.
If left unspecified, the module name will be computed based on the target's
build label, by stripping the leading //
and replacing /
, :
, and other
non-identifier characters with underscores.
srcs
A list of .swift
source files that will be compiled into the library.
stamp
Enable or disable link stamping; that is, whether to encode build information into the binary. Possible values are:
stamp = 1
: Stamp the build information into the binary. Stamped binaries are only rebuilt when their dependencies change. Use this if there are tests that depend on the build information.stamp = 0
: Always replace build information by constant values. This gives good build result caching.stamp = -1
: Embedding of build information is controlled by the--[no]stamp
flag.
swiftc_inputs
Additional files that are referenced using $(location ...)
in attributes that
support location expansion.