From a4103f891b5390edaf4a1d9b1674ecdf7090ad10 Mon Sep 17 00:00:00 2001 From: Tony Allevato Date: Mon, 16 Aug 2021 08:30:01 -0700 Subject: [PATCH] Allow both the `clang` and `swift` arguments of `swift_common.create_module` to be `None`. PiperOrigin-RevId: 391051966 (cherry picked from commit 19dcd00853c07404743aa524d727579435d8e1c6) --- doc/api.md | 19 +++++++++++++++---- swift/internal/providers.bzl | 21 +++++++++++++++------ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/doc/api.md b/doc/api.md index 9a3090d5a..034f508a2 100644 --- a/doc/api.md +++ b/doc/api.md @@ -262,10 +262,21 @@ swift_common.create_module(name, 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 -valid for both to be present; this is the case for most Swift modules, which -provide both Swift module artifacts as well as a generated header/module map -for Objective-C targets to depend on. +It is possible for both `clang` and `swift` to be present; this is the case +for Swift modules that generate an Objective-C header, where the Swift +module artifacts are propagated in the `swift` context and the generated +header and module map are propagated in the `clang` context. + +Though rare, it is also permitted for both the `clang` and `swift` arguments +to be `None`. One example of how this can be used is to model system +dependencies (like Apple SDK frameworks) that are implicitly available as +part of a non-hermetic SDK (Xcode) but do not propagate any artifacts of +their own. This would only apply in a build using implicit modules, however; +when using explicit modules, one would propagate the module artifacts +explicitly. But allowing for the empty case keeps the build graph consistent +if switching between the two modes is necessary, since it will not change +the set of transitive module names that are propagated by dependencies +(which other build rules may want to depend on for their own analysis). **PARAMETERS** diff --git a/swift/internal/providers.bzl b/swift/internal/providers.bzl index c2a576e8c..e3feed0f6 100644 --- a/swift/internal/providers.bzl +++ b/swift/internal/providers.bzl @@ -243,10 +243,21 @@ provider. 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 - valid for both to be present; this is the case for most Swift modules, which - provide both Swift module artifacts as well as a generated header/module map - for Objective-C targets to depend on. + It is possible for both `clang` and `swift` to be present; this is the case + for Swift modules that generate an Objective-C header, where the Swift + module artifacts are propagated in the `swift` context and the generated + header and module map are propagated in the `clang` context. + + Though rare, it is also permitted for both the `clang` and `swift` arguments + to be `None`. One example of how this can be used is to model system + dependencies (like Apple SDK frameworks) that are implicitly available as + part of a non-hermetic SDK (Xcode) but do not propagate any artifacts of + their own. This would only apply in a build using implicit modules, however; + when using explicit modules, one would propagate the module artifacts + explicitly. But allowing for the empty case keeps the build graph consistent + if switching between the two modes is necessary, since it will not change + the set of transitive module names that are propagated by dependencies + (which other build rules may want to depend on for their own analysis). Args: name: The name of the module. @@ -278,8 +289,6 @@ def create_module(*, name, clang = None, is_system = False, swift = None): A `struct` containing the `name`, `clang`, `is_system`, and `swift` fields provided as arguments. """ - if clang == None and swift == None: - fail("Must provide at least a clang or swift module.") return struct( clang = clang, is_system = is_system,