Skip to content

Commit

Permalink
Define swift_compiler_plugin_import to support pre-built compiler p…
Browse files Browse the repository at this point in the history
…lugins, and add a `plugins` attribute to `swift_import`

PiperOrigin-RevId: 633256010
(cherry picked from commit c77187b)
Signed-off-by: Brentley Jones <github@brentleyjones.com>
  • Loading branch information
allevato authored and brentleyjones committed Oct 15, 2024
1 parent c523f48 commit fff6015
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 16 deletions.
1 change: 1 addition & 0 deletions doc/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ _DOC_SRCS = {
"swift_binary",
"swift_compiler_plugin",
"universal_swift_compiler_plugin",
"swift_compiler_plugin_import",
"swift_cross_import_overlay",
"swift_feature_allowlist",
"swift_import",
Expand Down
5 changes: 5 additions & 0 deletions doc/doc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ load(
_swift_compiler_plugin = "swift_compiler_plugin",
_universal_swift_compiler_plugin = "universal_swift_compiler_plugin",
)
load(
"//swift:swift_compiler_plugin_import.bzl",
_swift_compiler_plugin_import = "swift_compiler_plugin_import",
)
load(
"//swift:swift_cross_import_overlay.bzl",
_swift_cross_import_overlay = "swift_cross_import_overlay",
Expand Down Expand Up @@ -118,6 +122,7 @@ SwiftToolchainInfo = _SwiftToolchainInfo
swift_binary = _swift_binary
swift_compiler_plugin = _swift_compiler_plugin
universal_swift_compiler_plugin = _universal_swift_compiler_plugin
swift_compiler_plugin_import = _swift_compiler_plugin_import
swift_cross_import_overlay = _swift_cross_import_overlay
swift_feature_allowlist = _swift_feature_allowlist
swift_import = _swift_import
Expand Down
43 changes: 35 additions & 8 deletions doc/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ On this page:
* [swift_binary](#swift_binary)
* [swift_compiler_plugin](#swift_compiler_plugin)
* [universal_swift_compiler_plugin](#universal_swift_compiler_plugin)
* [swift_compiler_plugin_import](#swift_compiler_plugin_import)
* [swift_cross_import_overlay](#swift_cross_import_overlay)
* [swift_feature_allowlist](#swift_feature_allowlist)
* [swift_import](#swift_import)
Expand Down Expand Up @@ -166,6 +167,28 @@ swift_library(
| <a id="swift_compiler_plugin-swiftc_inputs"></a>swiftc_inputs | Additional files that are referenced using `$(location ...)` in attributes that support location expansion. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |


<a id="swift_compiler_plugin_import"></a>

## swift_compiler_plugin_import

<pre>
swift_compiler_plugin_import(<a href="#swift_compiler_plugin_import-name">name</a>, <a href="#swift_compiler_plugin_import-executable">executable</a>, <a href="#swift_compiler_plugin_import-module_names">module_names</a>)
</pre>

Allows for a Swift compiler plugin to be loaded from a prebuilt executable or
some other binary-propagating rule, instead of building the plugin from source
using `swift_compiler_plugin`.

**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="swift_compiler_plugin_import-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
| <a id="swift_compiler_plugin_import-executable"></a>executable | The compiler plugin executable that will be passed to the Swift compiler when compiling any modules that depend on the plugin. This attribute may refer directly to an executable binary or to another rule that produces an executable binary. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="swift_compiler_plugin_import-module_names"></a>module_names | The list of names of Swift modules in the plugin executable that provide implementations of plugin types, which the compiler uses to look up their implementations. | List of strings | required | |


<a id="swift_cross_import_overlay"></a>

## swift_cross_import_overlay
Expand Down Expand Up @@ -243,23 +266,26 @@ package.
## swift_import

<pre>
swift_import(<a href="#swift_import-name">name</a>, <a href="#swift_import-deps">deps</a>, <a href="#swift_import-data">data</a>, <a href="#swift_import-archives">archives</a>, <a href="#swift_import-module_name">module_name</a>, <a href="#swift_import-swiftdoc">swiftdoc</a>, <a href="#swift_import-swiftinterface">swiftinterface</a>, <a href="#swift_import-swiftmodule">swiftmodule</a>)
swift_import(<a href="#swift_import-name">name</a>, <a href="#swift_import-deps">deps</a>, <a href="#swift_import-data">data</a>, <a href="#swift_import-archives">archives</a>, <a href="#swift_import-module_name">module_name</a>, <a href="#swift_import-plugins">plugins</a>, <a href="#swift_import-swiftdoc">swiftdoc</a>, <a href="#swift_import-swiftinterface">swiftinterface</a>,
<a href="#swift_import-swiftmodule">swiftmodule</a>)
</pre>

Allows for the use of Swift textual module interfaces or precompiled Swift modules as dependencies in other
`swift_library` and `swift_binary` targets.
Allows for the use of Swift textual module interfaces and/or precompiled Swift
modules as dependencies in other `swift_library` and `swift_binary` targets.

To use `swift_import` targets across Xcode versions and/or OS versions, it is required to use `.swiftinterface` files.
These can be produced by the pre-built target if built with:
To use `swift_import` targets across Xcode versions and/or OS versions, it is
required to use `.swiftinterface` files. These can be produced by the pre-built
target if built with:

- `--features=swift.enable_library_evolution`
- `--features=swift.emit_swiftinterface`

If the pre-built target supports `.private.swiftinterface` files, these can be used instead of `.swiftinterface` files
in the `swiftinterface` attribute.
If the pre-built target supports `.private.swiftinterface` files, these can be
used instead of `.swiftinterface` files in the `swiftinterface` attribute.

To import pre-built Swift modules that use `@_spi` when using `swiftinterface`,
the `.private.swiftinterface` files are required in order to build any code that uses the API marked with `@_spi`.
the `.private.swiftinterface` files are required in order to build any code that
uses the API marked with `@_spi`.

**ATTRIBUTES**

Expand All @@ -271,6 +297,7 @@ the `.private.swiftinterface` files are required in order to build any code that
| <a id="swift_import-data"></a>data | The list of files needed by this target at runtime.<br><br>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. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="swift_import-archives"></a>archives | The list of `.a` or `.lo` files provided to Swift targets that depend on this target. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="swift_import-module_name"></a>module_name | The name of the module represented by this target. | String | required | |
| <a id="swift_import-plugins"></a>plugins | A list of `swift_compiler_plugin` targets that should be loaded by the compiler when compiling any modules that directly depend on this target. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="swift_import-swiftdoc"></a>swiftdoc | The `.swiftdoc` file provided to Swift targets that depend on this target. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
| <a id="swift_import-swiftinterface"></a>swiftinterface | The `.swiftinterface` file that defines the module interface for this target. May not be specified if `swiftmodule` is specified. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
| <a id="swift_import-swiftmodule"></a>swiftmodule | The `.swiftmodule` file provided to Swift targets that depend on this target. May not be specified if `swiftinterface` is specified. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
Expand Down
9 changes: 9 additions & 0 deletions swift/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ bzl_library(
],
)

bzl_library(
name = "swift_compiler_plugin_import",
srcs = ["swift_compiler_plugin_import.bzl"],
deps = [
"//swift/internal:providers",
],
)

bzl_library(
name = "swift_cross_import_overlay",
srcs = ["swift_cross_import_overlay.bzl"],
Expand Down Expand Up @@ -293,6 +301,7 @@ bzl_library(
":swift_clang_module_aspect",
":swift_common",
":swift_compiler_plugin",
":swift_compiler_plugin_import",
":swift_cross_import_overlay",
":swift_extract_symbol_graph",
":swift_feature_allowlist",
Expand Down
58 changes: 58 additions & 0 deletions swift/swift_compiler_plugin_import.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2024 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Implementation of the `swift_compiler_plugin_import` rule."""

load("//swift/internal:providers.bzl", "SwiftCompilerPluginInfo")

def _swift_compiler_plugin_import_impl(ctx):
return [
SwiftCompilerPluginInfo(
executable = ctx.executable.executable,
module_names = depset(ctx.attr.module_names),
),
]

swift_compiler_plugin_import = rule(
attrs = {
"executable": attr.label(
allow_files = True,
cfg = "exec",
doc = """\
The compiler plugin executable that will be passed to the Swift compiler when
compiling any modules that depend on the plugin. This attribute may refer
directly to an executable binary or to another rule that produces an executable
binary.
""",
executable = True,
mandatory = True,
),
"module_names": attr.string_list(
allow_empty = False,
doc = """
The list of names of Swift modules in the plugin executable that provide
implementations of plugin types, which the compiler uses to look up their
implementations.
""",
mandatory = True,
),
},
doc = """\
Allows for a Swift compiler plugin to be loaded from a prebuilt executable or
some other binary-propagating rule, instead of building the plugin from source
using `swift_compiler_plugin`.
""",
implementation = _swift_compiler_plugin_import_impl,
provides = [SwiftCompilerPluginInfo],
)
33 changes: 25 additions & 8 deletions swift/swift_import.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ load(
"get_cc_feature_configuration",
)
load("//swift/internal:linking.bzl", "new_objc_provider")
load("//swift/internal:providers.bzl", "SwiftCompilerPluginInfo")
load(
"//swift/internal:toolchain_utils.bzl",
"get_swift_toolchain",
Expand Down Expand Up @@ -125,6 +126,11 @@ def _swift_import_impl(ctx):
module_map = None,
),
swift = create_swift_module_inputs(
plugins = [
plugin[SwiftCompilerPluginInfo]
for plugin in ctx.attr.plugins
if SwiftCompilerPluginInfo in plugin
],
swiftdoc = swiftdoc,
swiftinterface = swiftinterface,
swiftmodule = swiftmodule,
Expand Down Expand Up @@ -173,14 +179,23 @@ swift_import = rule(
allow_empty = True,
allow_files = ["a", "lo"],
doc = """\
The list of `.a` or `.lo` files provided to Swift targets that depend on this target.
The list of `.a` or `.lo` files provided to Swift targets that depend on this
target.
""",
mandatory = False,
),
"module_name": attr.string(
doc = "The name of the module represented by this target.",
mandatory = True,
),
"plugins": attr.label_list(
cfg = "exec",
doc = """\
A list of `swift_compiler_plugin` targets that should be loaded by the compiler
when compiling any modules that directly depend on this target.
""",
providers = [[SwiftCompilerPluginInfo]],
),
"swiftdoc": attr.label(
allow_single_file = ["swiftdoc"],
doc = """\
Expand Down Expand Up @@ -209,20 +224,22 @@ May not be specified if `swiftinterface` is specified.
},
),
doc = """\
Allows for the use of Swift textual module interfaces or precompiled Swift modules as dependencies in other
`swift_library` and `swift_binary` targets.
Allows for the use of Swift textual module interfaces and/or precompiled Swift
modules as dependencies in other `swift_library` and `swift_binary` targets.
To use `swift_import` targets across Xcode versions and/or OS versions, it is required to use `.swiftinterface` files.
These can be produced by the pre-built target if built with:
To use `swift_import` targets across Xcode versions and/or OS versions, it is
required to use `.swiftinterface` files. These can be produced by the pre-built
target if built with:
- `--features=swift.enable_library_evolution`
- `--features=swift.emit_swiftinterface`
If the pre-built target supports `.private.swiftinterface` files, these can be used instead of `.swiftinterface` files
in the `swiftinterface` attribute.
If the pre-built target supports `.private.swiftinterface` files, these can be
used instead of `.swiftinterface` files in the `swiftinterface` attribute.
To import pre-built Swift modules that use `@_spi` when using `swiftinterface`,
the `.private.swiftinterface` files are required in order to build any code that uses the API marked with `@_spi`.
the `.private.swiftinterface` files are required in order to build any code that
uses the API marked with `@_spi`.
""",
fragments = ["cpp"],
implementation = _swift_import_impl,
Expand Down

0 comments on commit fff6015

Please sign in to comment.