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

Commit

Permalink
Allow modules propagated by SwiftInfo to indicate whether they are …
Browse files Browse the repository at this point in the history
…system modules.

System modules differ from non-system modules in that we don't pass the module map to the compiler via `-fmodule-map-file` for system modules in implicit module builds, only in explicit module builds. This is because module maps passed via `-fmodule-map-file` are always treated as non-system modules, which affects how diagnostics are emitted when their headers are parsed, and some Swift modules like `SwiftOverlayShims` don't declare themselves as `[system]` in their module map file but contain small nullability issues. Such headers *must* be found through a standard header search via a system path like `-isystem` so that they don't cause builds to fail if they treat warnings more severely.

PiperOrigin-RevId: 351896080
  • Loading branch information
allevato authored and swiple-rules-gardener committed Jan 15, 2021
1 parent 5b1aabd commit 2140619
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
33 changes: 21 additions & 12 deletions swift/internal/compiling.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ def _collect_clang_module_inputs(
# Add the module map, which we use for both implicit and explicit module
# builds. For implicit module builds, we don't worry about the headers
# above because we collect the full transitive header set below.
if not types.is_string(module_map):
if not module.is_system and not types.is_string(module_map):
module_inputs.append(module_map)

# If we prefer textual module maps and headers for the build, fall back to
Expand All @@ -792,30 +792,36 @@ def _collect_clang_module_inputs(
transitive_inputs = header_depsets,
)

def _clang_modulemap_dependency_args(module):
def _clang_modulemap_dependency_args(module, ignore_system = True):
"""Returns a `swiftc` argument for the module map of a Clang module.
Args:
module: A struct containing information about the module, as defined by
`swift_common.create_module`.
ignore_system: If `True` and the module is a system module, no flag
should be returned. Defaults to `True`.
Returns:
The argument to pass to `swiftc` (without the `-Xcc` prefix).
A list of arguments, possibly empty, to pass to `swiftc` (without the
`-Xcc` prefix).
"""
if module.is_system and ignore_system:
return []

module_map = module.clang.module_map
if types.is_string(module_map):
module_map_path = module_map
else:
module_map_path = module_map.path

return "-fmodule-map-file={}".format(module_map_path)
return ["-fmodule-map-file={}".format(module_map_path)]

def _clang_module_dependency_args(module):
"""Returns `swiftc` arguments for a precompiled Clang module, if possible.
If a precompiled module is present for this module, then flags for both it
and the module map are returned (the latter is required in order to map
headers to mdules in some scenarios, since the precompiled modules are
headers to modules in some scenarios, since the precompiled modules are
passed by name). If no precompiled module is present for this module, then
this function falls back to the textual module map alone.
Expand All @@ -824,19 +830,22 @@ def _clang_module_dependency_args(module):
`swift_common.create_module`.
Returns:
A list of arguments to pass to `swiftc` (without the `-Xcc` prefix).
A list of arguments, possibly empty, to pass to `swiftc` (without the
`-Xcc` prefix).
"""
args = []
if module.clang.precompiled_module:
args.append(
# If we're consuming an explicit module, we must also provide the
# textual module map, whether or not it's a system module.
return [
"-fmodule-file={}={}".format(
module.name,
module.clang.precompiled_module.path,
),
)
if module.clang.module_map:
args.append(_clang_modulemap_dependency_args(module))
return args
] + _clang_modulemap_dependency_args(module, ignore_system = False)
else:
# If we have no explicit module, then only include module maps for
# non-system modules.
return _clang_modulemap_dependency_args(module)

def _dependencies_clang_modulemaps_configurator(prerequisites, args):
"""Configures Clang module maps from dependencies."""
Expand Down
23 changes: 19 additions & 4 deletions swift/internal/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ provider.
},
)

def create_module(*, name, clang = None, swift = None):
def create_module(*, name, clang = None, is_system = False, swift = None):
"""Creates a value containing Clang/Swift module artifacts of a dependency.
At least one of the `clang` and `swift` arguments must not be `None`. It is
Expand All @@ -187,20 +187,35 @@ def create_module(*, name, clang = None, swift = None):
contains artifacts related to Clang modules, such as a module map or
precompiled module. This may be `None` if the module is a pure Swift
module with no generated Objective-C interface.
is_system: Indicates whether the module is a system module. The default
value is `False`. System modules differ slightly from non-system
modules in the way that they are passed to the compiler. For
example, non-system modules have their Clang module maps passed to
the compiler in both implicit and explicit module builds. System
modules, on the other hand, do not have their module maps passed to
the compiler in implicit module builds because there is currently no
way to indicate that modules declared in a file passed via
`-fmodule-map-file` should be treated as system modules even if they
aren't declared with the `[system]` attribute, and some system
modules may not build cleanly with respect to warnings otherwise.
Therefore, it is assumed that any module with `is_system == True`
must be able to be found using import search paths in order for
implicit module builds to succeed.
swift: A value returned by `swift_common.create_swift_module` that
contains artifacts related to Swift modules, such as the
`.swiftmodule`, `.swiftdoc`, and/or `.swiftinterface` files emitted
by the compiler. This may be `None` if the module is a pure
C/Objective-C module.
Returns:
A `struct` containing the `name`, `clang`, and `swift` fields provided
as arguments.
A `struct` containing the `name`, `clang`, `is_system`, and `swift`
fields provided as arguments.
"""
if clang == None and swift == None:
fail("Must provide atleast a clang or swift module.")
fail("Must provide at least a clang or swift module.")
return struct(
clang = clang,
is_system = is_system,
name = name,
swift = swift,
)
Expand Down

0 comments on commit 2140619

Please sign in to comment.