Skip to content
This repository has been archived by the owner on Jan 25, 2024. It is now read-only.

Commit

Permalink
Support implicit C/Objective-C dependencies that are passed when comp…
Browse files Browse the repository at this point in the history
…iling any explicit Clang module.

The toolchain's `clang_implicit_deps` are not passed to Swift compilations;
only to actions that compile an explicit C/Objective-C module using
`swift_common.precompile_clang_module`.

PiperOrigin-RevId: 375816204
  • Loading branch information
allevato authored and swiple-rules-gardener committed May 25, 2021
1 parent 407b1c8 commit 9afbc30
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 20 deletions.
34 changes: 22 additions & 12 deletions swift/internal/compiling.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -1526,9 +1526,7 @@ def compile(
is_swift_generated_header = True,
module_map_file = compile_outputs.generated_module_map_file,
module_name = module_name,
swift_info = create_swift_info(
swift_infos = generated_module_deps_swift_infos,
),
swift_infos = generated_module_deps_swift_infos,
swift_toolchain = swift_toolchain,
target_name = target_name,
)
Expand Down Expand Up @@ -1574,7 +1572,7 @@ def precompile_clang_module(
target_name,
bin_dir = None,
genfiles_dir = None,
swift_info = None):
swift_infos = []):
"""Precompiles an explicit Clang module that is compatible with Swift.
Args:
Expand Down Expand Up @@ -1607,8 +1605,8 @@ def precompile_clang_module(
path is added to ClangImporter's header search paths for
compatibility with Bazel's C++ and Objective-C rules which support
inclusions of generated headers from that location.
swift_info: A `SwiftInfo` provider that contains dependencies required
to compile this module.
swift_infos: A list of `SwiftInfo` providers representing dependencies
required to compile this module.
Returns:
A `File` representing the precompiled module (`.pcm`) file, or `None` if
Expand All @@ -1623,7 +1621,7 @@ def precompile_clang_module(
is_swift_generated_header = False,
module_map_file = module_map_file,
module_name = module_name,
swift_info = swift_info,
swift_infos = swift_infos,
swift_toolchain = swift_toolchain,
target_name = target_name,
)
Expand All @@ -1640,7 +1638,7 @@ def _precompile_clang_module(
target_name,
bin_dir = None,
genfiles_dir = None,
swift_info = None):
swift_infos = []):
"""Precompiles an explicit Clang module that is compatible with Swift.
Args:
Expand Down Expand Up @@ -1675,8 +1673,8 @@ def _precompile_clang_module(
path is added to ClangImporter's header search paths for
compatibility with Bazel's C++ and Objective-C rules which support
inclusions of generated headers from that location.
swift_info: A `SwiftInfo` provider that contains dependencies required
to compile this module.
swift_infos: A list of `SwiftInfo` providers representing dependencies
required to compile this module.
Returns:
A `File` representing the precompiled module (`.pcm`) file, or `None` if
Expand All @@ -1702,8 +1700,20 @@ def _precompile_clang_module(
target_name = target_name,
)

if swift_info:
transitive_modules = swift_info.transitive_modules.to_list()
if not is_swift_generated_header:
implicit_swift_infos = (
swift_toolchain.clang_implicit_deps_providers.swift_infos
)
else:
implicit_swift_infos = []

if not is_swift_generated_header and implicit_swift_infos:
swift_infos = list(swift_infos)
swift_infos.extend(implicit_swift_infos)

if swift_infos:
merged_swift_info = create_swift_info(swift_infos = swift_infos)
transitive_modules = merged_swift_info.transitive_modules.to_list()
else:
transitive_modules = []

Expand Down
15 changes: 15 additions & 0 deletions swift/internal/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,21 @@ using this toolchain.
"cc_toolchain_info": """\
The `cc_common.CcToolchainInfo` provider from the Bazel C++ toolchain that this
Swift toolchain depends on.
""",
"clang_implicit_deps_providers": """\
A `struct` with the following fields, which represent providers from targets
that should be added as implicit dependencies of any precompiled explicit
C/Objective-C modules:
* `cc_infos`: A list of `CcInfo` providers from targets specified as the
toolchain's implicit dependencies.
* `objc_infos`: A list of `apple_common.Objc` providers from targets specified
as the toolchain's implicit dependencies.
* `swift_infos`: A list of `SwiftInfo` providers from targets specified as the
toolchain's implicit dependencies.
For ease of use, this field is never `None`; it will always be a valid `struct`
containing the fields described above, even if those lists are empty.
""",
"cpu": """\
`String`. The CPU architecture that the toolchain is targeting.
Expand Down
15 changes: 7 additions & 8 deletions swift/internal/swift_clang_module_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,14 @@ def _handle_module(
"""
attr = aspect_ctx.rule.attr

if swift_infos:
merged_swift_info = create_swift_info(swift_infos = swift_infos)
else:
merged_swift_info = None
all_swift_infos = (
swift_infos + swift_toolchain.clang_implicit_deps_providers.swift_infos
)

# Collect the names of Clang modules that the module being built directly
# depends on.
dependent_module_names = []
for swift_info in swift_infos:
for swift_info in all_swift_infos:
for module in swift_info.direct_modules:
if module.clang:
dependent_module_names.append(module.name)
Expand All @@ -450,8 +449,8 @@ def _handle_module(
)

if not module_map_file:
if merged_swift_info:
return [merged_swift_info]
if all_swift_infos:
return [create_swift_info(swift_infos = swift_infos)]
else:
return []

Expand All @@ -474,7 +473,7 @@ def _handle_module(
genfiles_dir = aspect_ctx.genfiles_dir,
module_map_file = module_map_file,
module_name = module_name,
swift_info = merged_swift_info,
swift_infos = swift_infos,
swift_toolchain = swift_toolchain,
target_name = target.label.name,
)
Expand Down
3 changes: 3 additions & 0 deletions swift/internal/swift_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ def _swift_toolchain_impl(ctx):
action_configs = all_action_configs,
all_files = depset(all_files),
cc_toolchain_info = cc_toolchain,
clang_implicit_deps_providers = (
collect_implicit_deps_providers([])
),
cpu = ctx.attr.arch,
feature_allowlists = [
target[SwiftFeatureAllowlistInfo]
Expand Down
19 changes: 19 additions & 0 deletions swift/internal/xcode_swift_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,9 @@ def _xcode_swift_toolchain_impl(ctx):
action_configs = all_action_configs,
all_files = depset(all_files),
cc_toolchain_info = cc_toolchain,
clang_implicit_deps_providers = collect_implicit_deps_providers(
ctx.attr.clang_implicit_deps,
),
cpu = cpu,
feature_allowlists = [
target[SwiftFeatureAllowlistInfo]
Expand Down Expand Up @@ -764,6 +767,22 @@ xcode_swift_toolchain = rule(
attrs = dicts.add(
swift_toolchain_driver_attrs(),
{
"clang_implicit_deps": attr.label_list(
doc = """\
A list of labels to library targets that should be unconditionally added as
implicit dependencies of any explicit C/Objective-C module compiled by the Swift
toolchain.
Despite being C/Objective-C modules, the targets specified by this attribute
must propagate the `SwiftInfo` provider because the Swift build rules use that
provider to look up Clang module requirements. In particular, the targets must
propagate the provider in their rule implementation themselves and not rely on
the implicit traversal performed by `swift_clang_module_aspect`; the latter is
not possible as it would create a dependency cycle between the toolchain and the
implicit dependencies.
""",
providers = [[SwiftInfo]],
),
"feature_allowlists": attr.label_list(
doc = """\
A list of `swift_feature_allowlist` targets that allow or prohibit packages from
Expand Down

0 comments on commit 9afbc30

Please sign in to comment.