diff --git a/swift/internal/compiling.bzl b/swift/internal/compiling.bzl index 088a21a10..8dbb2439e 100644 --- a/swift/internal/compiling.bzl +++ b/swift/internal/compiling.bzl @@ -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 @@ -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. @@ -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.""" diff --git a/swift/internal/providers.bzl b/swift/internal/providers.bzl index 449181eda..4d377c776 100644 --- a/swift/internal/providers.bzl +++ b/swift/internal/providers.bzl @@ -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 @@ -187,6 +187,20 @@ 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 @@ -194,13 +208,14 @@ def create_module(*, name, clang = None, swift = None): 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, )