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 and swift_library (or anything propagating SwiftInfo)

  • cc_library (or anything propagating CcInfo)

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:

  1. Use an auto-generated module map. In this case, the swift_c_module rule is not needed. If a cc_library is a direct dependency of a swift_{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 the swift_module tag on the cc_library; e.g., tags = ["swift_module=MyModule"].

  2. 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. The cc_library targets that contain the headers that you wish to expose to Swift should be listed in the deps of your swift_c_module (and by listing multiple targets, you can export multiple libraries under a single module if desired). Then, your swift_{binary,library,test} targets should depend on the swift_c_module target, not on the underlying cc_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_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 and swift_library (or anything propagating SwiftInfo)

  • cc_library (or anything propagating CcInfo)

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.

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 and swift_library (or anything propagating SwiftInfo)

  • cc_library (or anything propagating CcInfo)

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 and swift_library (or anything propagating SwiftInfo)

  • cc_library (or anything propagating CcInfo)

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 the deps 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 and swift_library (or anything propagating SwiftInfo)

  • cc_library (or anything propagating CcInfo)

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.