Skip to content

Commit

Permalink
Partially unify Objective-C and C++ module map generation for Swift.
Browse files Browse the repository at this point in the history
Now that Objective-C targets have accurate compilation contexts, we can
start using those to access the headers of the library for the purposes
of propagation. We do not completely switch over to having the aspect
generate module maps for Objective-C rules yet, though.

We also add `use` declarations to the module maps generated by the Swift
build rules to match the ones now generated by Bazel for the Objective-C
targets. These are not currently enabled, however; in the future we can
enable `-fmodules-decluse` to provide layering checks among C modules
used by Swift.

RELNOTES: None.
PiperOrigin-RevId: 318342672
  • Loading branch information
allevato authored and swiple-rules-gardener committed Jun 25, 2020
1 parent 8db6c90 commit da184ed
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 155 deletions.
8 changes: 8 additions & 0 deletions swift/internal/feature_names.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ SWIFT_FEATURE_MINIMAL_DEPS = "swift.minimal_deps"
# relative to the location of the module map file.
SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD = "swift.module_map_home_is_cwd"

# If enabled, private headers (headers specified in the `srcs` of a target) will
# not be included in generated module maps.
# TODO(b/142867898): This only exists for compatibility with the existing
# Objective-C behavior in Bazel and should be removed.
SWIFT_FEATURE_MODULE_MAP_NO_PRIVATE_HEADERS = (
"swift.module_map_no_private_headers"
)

# If enabled, the compilation action for a library target will not generate an
# Objective-C header for the module. This feature also implies
# `swift.no_generated_module_map`.
Expand Down
52 changes: 42 additions & 10 deletions swift/internal/module_maps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,41 +20,73 @@ def write_module_map(
actions,
module_map_file,
module_name,
headers = [],
textual_headers = [],
dependent_module_names = [],
public_headers = [],
public_textual_headers = [],
private_headers = [],
private_textual_headers = [],
workspace_relative = False):
"""Writes the content of the module map to a file.
Args:
actions: The actions object from the aspect context.
module_map_file: A `File` representing the module map being written.
module_name: The name of the module being generated.
headers: The `list` of `File`s representing the public headers of the
target whose module map is being written.
textual_headers: The `list` of `File`s representing the textual headers
of the target whose module map is being written.
dependent_module_names: A `list` of names of Clang modules that are
direct dependencies of the target whose module map is being written.
public_headers: The `list` of `File`s representing the public modular
headers of the target whose module map is being written.
public_textual_headers: The `list` of `File`s representing the public
textual headers of the target whose module map is being written.
private_headers: The `list` of `File`s representing the private modular
headers of the target whose module map is being written.
private_textual_headers: The `list` of `File`s representing the private
textual headers of the target whose module map is being written.
workspace_relative: A Boolean value indicating whether the header paths
written in the module map file should be relative to the workspace
or relative to the module map file.
"""
content = "module {} {{\n".format(module_name)
content = 'module "{}" {{\n'.format(module_name)
content += " export *\n\n"

content += "".join([
' header "{}"\n'.format(_header_path(
header_file = header_file,
module_map_file = module_map_file,
workspace_relative = workspace_relative,
))
for header_file in headers
for header_file in public_headers
])
content += "".join([
' private header "{}"\n'.format(_header_path(
header_file = header_file,
module_map_file = module_map_file,
workspace_relative = workspace_relative,
))
for header_file in private_headers
])
content += "".join([
' textual header "{}"\n'.format(_header_path(
header_file = header_file,
module_map_file = module_map_file,
workspace_relative = workspace_relative,
))
for header_file in textual_headers
for header_file in public_textual_headers
])
content += " export *\n"
content += "".join([
' private textual header "{}"\n'.format(_header_path(
header_file = header_file,
module_map_file = module_map_file,
workspace_relative = workspace_relative,
))
for header_file in private_textual_headers
])

content += "".join([
' use "{}"\n'.format(name)
for name in dependent_module_names
])

content += "}\n"

actions.write(
Expand Down
23 changes: 18 additions & 5 deletions swift/internal/swift_autoconfiguration.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ load(
"SWIFT_FEATURE_DEBUG_PREFIX_MAP",
"SWIFT_FEATURE_ENABLE_BATCH_MODE",
"SWIFT_FEATURE_IMPLICIT_MODULES",
"SWIFT_FEATURE_MODULE_MAP_NO_PRIVATE_HEADERS",
"SWIFT_FEATURE_SUPPORTS_PRIVATE_DEPS",
"SWIFT_FEATURE_USE_RESPONSE_FILES",
)
Expand Down Expand Up @@ -212,6 +213,11 @@ def _create_linux_toolchain(repository_ctx):
# (i.e., from the Swift toolchain) as explicit modules.
feature_values.append(SWIFT_FEATURE_IMPLICIT_MODULES)

# TODO: This should be removed so that private headers can be used with
# explicit modules, but the build targets for CgRPC need to be cleaned up
# first because they contain C++ code.
feature_values.append(SWIFT_FEATURE_MODULE_MAP_NO_PRIVATE_HEADERS)

repository_ctx.file(
"BUILD",
"""
Expand Down Expand Up @@ -248,11 +254,18 @@ def _create_xcode_toolchain(repository_ctx):
"""
path_to_swiftc = repository_ctx.which("swiftc")

# TODO: This is being enabled here, rather than in the toolchain rule
# implementations, so that we can provide a way to optionally turn it off
# later when we have a way to model modules from outside Bazel workspaces
# (i.e., from the Swift toolchain and Xcode SDKs) as explicit modules.
feature_values = [SWIFT_FEATURE_IMPLICIT_MODULES]
feature_values = [
# TODO: This is being enabled here, rather than in the toolchain rule
# implementations, so that we can provide a way to optionally turn it
# off later when we have a way to model modules from outside Bazel
# workspaces (i.e., from the Swift toolchain and Xcode SDKs) as explicit
# modules.
SWIFT_FEATURE_IMPLICIT_MODULES,
# TODO: This should be removed so that private headers can be used with
# explicit modules, but the build targets for CgRPC need to be cleaned
# up first because they contain C++ code.
SWIFT_FEATURE_MODULE_MAP_NO_PRIVATE_HEADERS,
]

repository_ctx.file(
"BUILD",
Expand Down
Loading

0 comments on commit da184ed

Please sign in to comment.