Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow opting out of the default umbrella header, to support strict imports #348

Merged
merged 3 commits into from
Nov 12, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 36 additions & 5 deletions rules/library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,23 @@ module {module_name} {{
)
return destination

def _write_umbrella_header(name, library_tools, public_headers = [], private_headers = [], module_name = None, **kwargs):
def _write_umbrella_header(
name,
library_tools,
generate_legacy_umbrella_header,
public_headers = [],
private_headers = [],
module_name = None,
**kwargs):
basename = "{name}-umbrella.h".format(name = name)
destination = paths.join(name + "-modulemap", basename)
if not module_name:
module_name = name
content = """\

content = ""

if generate_legacy_umbrella_header:
content += """\
#ifdef __OBJC__
# import <Foundation/Foundation.h>
# if __has_include(<UIKit/UIKit.h>)
Expand All @@ -148,12 +159,13 @@ def _write_umbrella_header(name, library_tools, public_headers = [], private_hea
for header in public_headers:
content += "#import \"{header}\"\n".format(header = paths.basename(header))

content += """
if generate_legacy_umbrella_header:
content += """
FOUNDATION_EXPORT double {module_name}VersionNumber;
FOUNDATION_EXPORT const unsigned char {module_name}VersionString[];
""".format(
module_name = module_name,
)
module_name = module_name,
)

write_file(
name = basename + "~",
Expand Down Expand Up @@ -439,6 +451,24 @@ def apple_library(name, library_tools = {}, export_private_headers = True, names
namespace = module_name if namespace_is_module_name else name
module_map = kwargs.pop("module_map", None)
swift_objc_bridging_header = kwargs.pop("swift_objc_bridging_header", None)

# Historically, xcode and cocoapods use an umbrella header that imports Foundation and UIKit at the
# beginning of it. See:
# * https://github.com/CocoaPods/CocoaPods/issues/6815#issuecomment-330046236
# * https://github.com/facebookarchive/xcbuild/issues/92#issuecomment-234372926
#
# As a result, when writing swift code, there is no need for importing neither Foundation nor
# UIKit. See:
# * https://github.com/facebookarchive/xcbuild/issues/92#issuecomment-234400427
#
# But these automatic imports are a problem when strict imports are wanted. See:
# * https://forums.swift.org/t/supporting-strict-imports/42472
#
# So provide here two behaviours:
# * By default, follow xcode and cocoapods and populate the umbrella header with the usual content
acecilia marked this conversation as resolved.
Show resolved Hide resolved
# * Optionally, allow the consumers to set generate_legacy_umbrella_header to False, so the
# generated umbrella header does not contain any imports
generate_legacy_umbrella_header = kwargs.pop("generate_legacy_umbrella_header", True)
cc_copts = kwargs.pop("cc_copts", [])
additional_cc_copts = []
swift_copts = kwargs.pop("swift_copts", [])
Expand Down Expand Up @@ -651,6 +681,7 @@ def apple_library(name, library_tools = {}, export_private_headers = True, names
umbrella_header = library_tools["umbrella_header_generator"](
name = name,
library_tools = library_tools,
generate_legacy_umbrella_header = generate_legacy_umbrella_header,
public_headers = objc_hdrs,
private_headers = objc_private_hdrs,
module_name = module_name,
Expand Down