Skip to content

Commit

Permalink
Make sure to pass strict dependency include paths from the `apple_com…
Browse files Browse the repository at this point in the history
…mon.Objc` provider when compiling the explicit module for a target.

Also clarify the purpose of the `compilation_context` argument in `swift_common.create_clang_module` and how it should and should not be used.

PiperOrigin-RevId: 391067469
  • Loading branch information
allevato authored and swiple-rules-gardener committed Aug 16, 2021
1 parent 19dcd00 commit a81c591
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 9 deletions.
25 changes: 22 additions & 3 deletions swift/internal/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -299,11 +299,30 @@ def create_clang_module(
precompiled_module = None):
"""Creates a value representing a Clang module used as a Swift dependency.
Note: The `compilation_context` argument of this function is primarily
intended to communicate information *to* the Swift build rules, not to
retrieve information *back out.* In most cases, it is better to depend on
the `CcInfo` provider propagated by a Swift target to collect transitive
C/Objective-C compilation information about that target. This is because the
context used when compiling the module itself may not be the same as the
context desired when depending on it. (For example, `apple_common.Objc`
supports "strict include paths" which are only propagated to direct
dependents.)
One valid exception to the guidance above is retrieving the generated header
associated with a specific Swift module. Since the `CcInfo` provider
propagated by the library will have already merged them transitively (or,
in the case of a hypothetical custom rule that propagates multiple direct
modules, the `direct_public_headers` of the `CcInfo` would also have them
merged), it is acceptable to read the headers from the compilation context
of the module struct itself in order to associate them with the module that
generated them.
Args:
compilation_context: A `CcCompilationContext` that contains the header
files, include paths, and other context necessary to compile targets
that depend on this module (if using the text module map instead of
the precompiled module).
files and other context (such as include paths, preprocessor
defines, and so forth) needed to compile this module as an explicit
module.
module_map: The text module map file that defines this module. This
argument may be specified as a `File` or as a `string`; in the
latter case, it is assumed to be the path to a file that cannot
Expand Down
41 changes: 35 additions & 6 deletions swift/internal/swift_clang_module_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -555,16 +555,45 @@ def _find_swift_interop_info(target, aspect_ctx):
return interop_target[_SwiftInteropInfo], default_swift_infos
return None, default_swift_infos

def _compilation_context_for_target(target):
"""Gets the compilation context to use when compiling this target's module.
This function also handles the special case of a target that propagates an
`apple_common.Objc` provider in addition to its `CcInfo` provider, where the
former contains strict include paths that must also be added when compiling
the module.
Args:
target: The target to which the aspect is being applied.
Returns:
A `CcCompilationContext` that contains the headers of the target being
compiled.
"""
if CcInfo not in target:
return None

compilation_context = target[CcInfo].compilation_context

if apple_common.Objc in target:
strict_includes = target[apple_common.Objc].strict_include
if strict_includes:
compilation_context = cc_common.merge_compilation_contexts(
compilation_contexts = [
compilation_context,
cc_common.create_compilation_context(
includes = strict_includes,
),
],
)

return compilation_context

def _swift_clang_module_aspect_impl(target, aspect_ctx):
# Do nothing if the target already propagates `SwiftInfo`.
if SwiftInfo in target:
return []

if CcInfo in target:
compilation_context = target[CcInfo].compilation_context
else:
compilation_context = None

requested_features = aspect_ctx.features
unsupported_features = aspect_ctx.disabled_features

Expand Down Expand Up @@ -592,7 +621,7 @@ def _swift_clang_module_aspect_impl(target, aspect_ctx):
if interop_info or apple_common.Objc in target or CcInfo in target:
return _handle_module(
aspect_ctx = aspect_ctx,
compilation_context = compilation_context,
compilation_context = _compilation_context_for_target(target),
feature_configuration = feature_configuration,
module_map_file = module_map_file,
module_name = module_name,
Expand Down

1 comment on commit a81c591

@thii
Copy link
Member

@thii thii commented on a81c591 Aug 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.