Skip to content

Commit

Permalink
Add index-while-building support (back) to the Swift build rules.
Browse files Browse the repository at this point in the history
When the `swift.index_while_building` feature is set, targets will emit an indexstore directory to the "indexstore" output group.

Unlike the original implementation, this one is focused on the remote indexing use case, so we don't support the old behavior meant for local builds of scanning `--swiftcopt` for a manually-specified path that would be the destination for all index data. Users who want to do that should just pass _all_ of the indexing flags to `--swiftcopt` instead of using this feature.

PiperOrigin-RevId: 459613898
  • Loading branch information
allevato authored and swiple-rules-gardener committed Jul 7, 2022
1 parent b100c3f commit 8150427
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 18 deletions.
52 changes: 40 additions & 12 deletions swift/internal/compiling.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ load(
":feature_names.bzl",
"SWIFT_FEATURE_EMIT_C_MODULE",
"SWIFT_FEATURE_EMIT_SWIFTINTERFACE",
"SWIFT_FEATURE_INDEX_WHILE_BUILDING",
"SWIFT_FEATURE_NO_GENERATED_MODULE_MAP",
"SWIFT_FEATURE_OPT",
"SWIFT_FEATURE_OPT_USES_WMO",
Expand Down Expand Up @@ -189,17 +190,26 @@ def compile(
outputs.
Returns:
A tuple containing two elements:
1. A Swift module context (as returned by `swift_common.create_module`)
that contains the Swift (and potentially C/Objective-C) compilation
prerequisites of the compiled module. This should typically be
propagated by a `SwiftInfo` provider of the calling rule, and the
`CcCompilationContext` inside the Clang module substructure should
be propagated by the `CcInfo` provider of the calling rule.
2. A `CcCompilationOutputs` object (as returned by
`cc_common.create_compilation_outputs`) that contains the compiled
object files.
A `struct` with the following fields:
* `module_context`: A Swift module context (as returned by
`swift_common.create_module`) that contains the Swift (and
potentially C/Objective-C) compilation prerequisites of the compiled
module. This should typically be propagated by a `SwiftInfo`
provider of the calling rule, and the `CcCompilationContext` inside
the Clang module substructure should be propagated by the `CcInfo`
provider of the calling rule.
* `compilation_outputs`: A `CcCompilationOutputs` object (as returned
by `cc_common.create_compilation_outputs`) that contains the
compiled object files.
* `supplemental_outputs`: A `struct` representing supplemental,
optional outputs. Its fields are:
* `indexstore_directory`: A directory-type `File` that represents
the indexstore output files created when the feature
`swift.index_while_building` is enabled.
"""

# Collect the `SwiftInfo` providers that represent the dependencies of the
Expand Down Expand Up @@ -234,6 +244,7 @@ def compile(
compile_outputs.swiftinterface_file,
compile_outputs.swiftsourceinfo_file,
compile_outputs.generated_header_file,
compile_outputs.indexstore_directory,
]) + compile_outputs.object_files

merged_compilation_context = merge_compilation_contexts(
Expand Down Expand Up @@ -379,7 +390,13 @@ def compile(
pic_objects = depset(compile_outputs.object_files),
)

return module_context, compilation_outputs
return struct(
module_context = module_context,
compilation_outputs = compilation_outputs,
supplemental_outputs = struct(
indexstore_directory = compile_outputs.indexstore_directory,
),
)

def precompile_clang_module(
*,
Expand Down Expand Up @@ -744,9 +761,20 @@ def _declare_compile_outputs(
object_files = output_info.object_files
output_file_map = output_info.output_file_map

if is_feature_enabled(
feature_configuration = feature_configuration,
feature_name = SWIFT_FEATURE_INDEX_WHILE_BUILDING,
):
indexstore_directory = actions.declare_directory(
"{}.indexstore".format(target_name),
)
else:
indexstore_directory = None

return struct(
generated_header_file = generated_header,
generated_module_map_file = generated_module_map,
indexstore_directory = indexstore_directory,
object_files = object_files,
output_file_map = output_file_map,
swiftdoc_file = swiftdoc_file,
Expand Down
4 changes: 4 additions & 0 deletions swift/internal/feature_names.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ SWIFT_FEATURE_DEBUG_PREFIX_MAP = "swift.debug_prefix_map"
# graph.
SWIFT_FEATURE_EMIT_C_MODULE = "swift.emit_c_module"

# If enabled, the compilation action for a target will also produce an index
# store among its outputs.
SWIFT_FEATURE_INDEX_WHILE_BUILDING = "swift.index_while_building"

# If enabled, when compiling an explicit C or Objectve-C module, every header
# included by the module being compiled must belong to one of the modules listed
# in its dependencies. This is ignored for system modules.
Expand Down
13 changes: 12 additions & 1 deletion swift/internal/swift_protoc_gen_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ def _swift_protoc_gen_aspect_impl(target, aspect_ctx):
if apple_common.Objc in p:
transitive_objc_infos.append(p[apple_common.Objc])

module_context, compilation_outputs = swift_common.compile(
compile_result = swift_common.compile(
actions = aspect_ctx.actions,
compilation_contexts = get_compilation_contexts(support_deps),
copts = ["-parse-as-library"],
Expand All @@ -421,6 +421,16 @@ def _swift_protoc_gen_aspect_impl(target, aspect_ctx):
target_name = target.label.name,
)

module_context = compile_result.module_context
compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs

output_groups = {}
if supplemental_outputs.indexstore_directory:
output_groups["indexstore"] = depset([
supplemental_outputs.indexstore_directory,
])

linking_context, linking_output = (
swift_common.create_linking_context_from_compilation_outputs(
actions = aspect_ctx.actions,
Expand Down Expand Up @@ -461,6 +471,7 @@ def _swift_protoc_gen_aspect_impl(target, aspect_ctx):
)

providers = [
OutputGroupInfo(**output_groups),
SwiftProtoCompilationInfo(
cc_info = cc_info,
objc_info = objc_info,
Expand Down
11 changes: 10 additions & 1 deletion swift/swift_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def _swift_binary_impl(ctx):
)

srcs = ctx.files.srcs
output_groups = {}

# If the binary has sources, compile those first and collect the outputs to
# be passed to the linker.
Expand All @@ -49,7 +50,7 @@ def _swift_binary_impl(ctx):
if not module_name:
module_name = swift_common.derive_module_name(ctx.label)

_, compilation_outputs = swift_common.compile(
compile_result = swift_common.compile(
actions = ctx.actions,
additional_inputs = ctx.files.swiftc_inputs,
compilation_contexts = get_compilation_contexts(ctx.attr.deps),
Expand All @@ -66,6 +67,13 @@ def _swift_binary_impl(ctx):
swift_toolchain = swift_toolchain,
target_name = ctx.label.name,
)
compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs

if supplemental_outputs.indexstore_directory:
output_groups["indexstore"] = depset([
supplemental_outputs.indexstore_directory,
])
else:
compilation_outputs = cc_common.create_compilation_outputs()

Expand Down Expand Up @@ -102,6 +110,7 @@ def _swift_binary_impl(ctx):
files = ctx.files.data,
),
),
OutputGroupInfo(**output_groups),
]

swift_binary = rule(
Expand Down
13 changes: 12 additions & 1 deletion swift/swift_grpc_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def _swift_grpc_library_impl(ctx):

module_name = swift_common.derive_module_name(ctx.label)

module_context, compilation_outputs = swift_common.compile(
compile_result = swift_common.compile(
actions = ctx.actions,
compilation_contexts = get_compilation_contexts(ctx.attr.deps),
copts = ["-parse-as-library"],
Expand All @@ -289,6 +289,16 @@ def _swift_grpc_library_impl(ctx):
target_name = ctx.label.name,
)

module_context = compile_result.module_context
compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs

output_groups = {}
if supplemental_outputs.indexstore_directory:
output_groups["indexstore"] = depset([
supplemental_outputs.indexstore_directory,
])

linking_context, linking_output = (
swift_common.create_linking_context_from_compilation_outputs(
actions = ctx.actions,
Expand Down Expand Up @@ -323,6 +333,7 @@ def _swift_grpc_library_impl(ctx):
modules = [module_context],
swift_infos = compile_deps_swift_infos,
),
OutputGroupInfo(**output_groups),
]

# Propagate an `apple_common.Objc` provider with linking info about the
Expand Down
13 changes: 12 additions & 1 deletion swift/swift_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def _swift_library_impl(ctx):
attr = "generated_header_name",
)

module_context, compilation_outputs = swift_common.compile(
compile_result = swift_common.compile(
actions = ctx.actions,
additional_inputs = additional_inputs,
compilation_contexts = get_compilation_contexts(ctx.attr.deps),
Expand All @@ -192,6 +192,16 @@ def _swift_library_impl(ctx):
target_name = ctx.label.name,
)

module_context = compile_result.module_context
compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs

output_groups = {}
if supplemental_outputs.indexstore_directory:
output_groups["indexstore"] = depset([
supplemental_outputs.indexstore_directory,
])

linking_context, linking_output = (
swift_common.create_linking_context_from_compilation_outputs(
actions = ctx.actions,
Expand Down Expand Up @@ -257,6 +267,7 @@ def _swift_library_impl(ctx):
# not propagate.
swift_infos = swift_infos,
),
OutputGroupInfo(**output_groups),
]

# Propagate an `apple_common.Objc` provider with linking info about the
Expand Down
13 changes: 12 additions & 1 deletion swift/swift_module_alias.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def _swift_module_alias_impl(ctx):

swift_infos = get_providers(deps, SwiftInfo)

module_context, compilation_outputs = swift_common.compile(
compile_result = swift_common.compile(
actions = ctx.actions,
compilation_contexts = get_compilation_contexts(ctx.attr.deps),
copts = ["-parse-as-library"],
Expand All @@ -74,6 +74,16 @@ def _swift_module_alias_impl(ctx):
target_name = ctx.label.name,
)

module_context = compile_result.module_context
compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs

output_groups = {}
if supplemental_outputs.indexstore_directory:
output_groups["indexstore"] = depset([
supplemental_outputs.indexstore_directory,
])

linking_context, linking_output = (
swift_common.create_linking_context_from_compilation_outputs(
actions = ctx.actions,
Expand Down Expand Up @@ -112,6 +122,7 @@ def _swift_module_alias_impl(ctx):
modules = [module_context],
swift_infos = swift_infos,
),
OutputGroupInfo(**output_groups),
]

# Propagate an `apple_common.Objc` provider with linking info about the
Expand Down
13 changes: 12 additions & 1 deletion swift/swift_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,14 @@ def _swift_test_impl(ctx):
elif is_bundled:
extra_deps = [ctx.attr._test_observer]

output_groups = {}

if srcs:
module_name = ctx.attr.module_name
if not module_name:
module_name = swift_common.derive_module_name(ctx.label)

_, compilation_outputs = swift_common.compile(
compile_result = swift_common.compile(
actions = ctx.actions,
additional_inputs = ctx.files.swiftc_inputs,
compilation_contexts = get_compilation_contexts(
Expand All @@ -250,6 +252,14 @@ def _swift_test_impl(ctx):
swift_toolchain = swift_toolchain,
target_name = ctx.label.name,
)

compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs

if supplemental_outputs.indexstore_directory:
output_groups["indexstore"] = depset([
supplemental_outputs.indexstore_directory,
])
else:
compilation_outputs = cc_common.create_compilation_outputs()

Expand Down Expand Up @@ -314,6 +324,7 @@ def _swift_test_impl(ctx):
transitive_files = ctx.attr._apple_coverage_support.files,
),
),
OutputGroupInfo(**output_groups),
coverage_common.instrumented_files_info(
ctx,
dependency_attributes = ["deps"],
Expand Down
13 changes: 13 additions & 0 deletions swift/toolchains/config/compile_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ load(
"SWIFT_FEATURE_ENABLE_TESTING",
"SWIFT_FEATURE_FASTBUILD",
"SWIFT_FEATURE_FULL_DEBUG_INFO",
"SWIFT_FEATURE_INDEX_WHILE_BUILDING",
"SWIFT_FEATURE_LAYERING_CHECK",
"SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD",
"SWIFT_FEATURE_NO_ASAN_VERSION_CHECK",
Expand Down Expand Up @@ -607,6 +608,13 @@ def compile_action_configs(
configurators = [_module_name_configurator],
),

# Configure index-while-building.
ActionConfigInfo(
actions = [SWIFT_ACTION_COMPILE],
configurators = [_index_while_building_configurator],
features = [SWIFT_FEATURE_INDEX_WHILE_BUILDING],
),

# User-defined conditional compilation flags (defined for Swift; those
# passed directly to ClangImporter are handled above).
ActionConfigInfo(
Expand Down Expand Up @@ -1071,6 +1079,11 @@ def _module_name_configurator(prerequisites, args):
"""Adds the module name flag to the command line."""
args.add("-module-name", prerequisites.module_name)

def _index_while_building_configurator(prerequisites, args):
"""Adds flags for indexstore generation to the command line."""
args.add("-index-ignore-system-modules")
args.add("-index-store-path", prerequisites.indexstore_directory.path)

def _source_files_configurator(prerequisites, args):
"""Adds source files to the command line and required inputs."""
args.add_all(prerequisites.source_files)
Expand Down

1 comment on commit 8150427

@brentleyjones
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.