diff --git a/MODULE.bazel b/MODULE.bazel
index 2f15a5e49..6346672d8 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -16,6 +16,8 @@ bazel_dep(name = "rules_shell", version = "0.3.0")
bazel_dep(name = "platforms", version = "0.0.9")
bazel_dep(name = "protobuf", version = "27.0", repo_name = "com_google_protobuf")
bazel_dep(name = "nlohmann_json", version = "3.6.1", repo_name = "com_github_nlohmann_json")
+bazel_dep(name = "abseil-cpp", version = "20250127.0")
+bazel_dep(name = "re2", version = "2024-07-02")
bazel_dep(
name = "swift_argument_parser",
version = "1.3.1.2",
diff --git a/doc/providers.md b/doc/providers.md
index cc8e6f712..95e6f97b2 100644
--- a/doc/providers.md
+++ b/doc/providers.md
@@ -140,7 +140,7 @@ that use the toolchain.
| package_configurations | A list of `SwiftPackageConfigurationInfo` providers that specify additional compilation configuration options that are applied to targets on a per-package basis. |
| requested_features | `List` of `string`s. Features that should be implicitly enabled by default for targets built using this toolchain, unless overridden by the user by listing their negation in the `features` attribute of a target/package or in the `--features` command line flag.
These features determine various compilation and debugging behaviors of the Swift build rules, and they are also passed to the C++ APIs used when linking (so features defined in CROSSTOOL may be used here). |
| root_dir | `String`. The workspace-relative root directory of the toolchain. |
-| swift_worker | `File`. The executable representing the worker executable used to invoke the compiler and other Swift tools (for both incremental and non-incremental compiles). |
+| swift_worker | `File`. The executable that wraps Swift compiler invocations. |
| test_configuration | `Struct` containing the following fields:
* `binary_name`: A template string used to compute the name of the output binary for `swift_test` rules. Any occurrences of the string `"{name}"` will be substituted by the name of the target.
* `env`: A `dict` of environment variables to be set when running tests that were built with this toolchain.
* `execution_requirements`: A `dict` of execution requirements for tests that were built with this toolchain.
* `objc_test_discovery`: A Boolean value indicating whether test targets should discover tests dynamically using the Objective-C runtime.
* `test_linking_contexts`: A list of `CcLinkingContext`s that provide additional flags to use when linking test binaries.
This is used, for example, with Xcode-based toolchains to ensure that the `xctest` helper and coverage tools are found in the correct developer directory when running tests. |
| tool_configs | This field is an internal implementation detail of the build rules. |
| unsupported_features | `List` of `string`s. Features that should be implicitly disabled by default for targets built using this toolchain, unless overridden by the user by listing them in the `features` attribute of a target/package or in the `--features` command line flag.
These features determine various compilation and debugging behaviors of the Swift build rules, and they are also passed to the C++ APIs used when linking (so features defined in CROSSTOOL may be used here). |
diff --git a/swift/internal/BUILD b/swift/internal/BUILD
index 7d47d8ae2..b4247541f 100644
--- a/swift/internal/BUILD
+++ b/swift/internal/BUILD
@@ -99,9 +99,9 @@ bzl_library(
":feature_names",
":features",
":module_maps",
+ ":optimization",
":utils",
":vfsoverlay",
- ":wmo",
"//swift:providers",
"@bazel_skylib//lib:paths",
"@bazel_skylib//lib:sets",
@@ -314,9 +314,8 @@ bzl_library(
)
bzl_library(
- name = "wmo",
- srcs = ["wmo.bzl"],
- visibility = ["//swift:__subpackages__"],
+ name = "optimization",
+ srcs = ["optimization.bzl"],
deps = [
":feature_names",
],
diff --git a/swift/internal/action_names.bzl b/swift/internal/action_names.bzl
index c14ad507c..351331c56 100644
--- a/swift/internal/action_names.bzl
+++ b/swift/internal/action_names.bzl
@@ -20,9 +20,17 @@
SWIFT_ACTION_AUTOLINK_EXTRACT = "SwiftAutolinkExtract"
# Compiles one or more `.swift` source files into a `.swiftmodule` and
-# object files.
+# object files. This is the legacy mode that emits all outputs from a single
+# driver invocation.
SWIFT_ACTION_COMPILE = "SwiftCompile"
+# Emits the object files and other per-source-file outputs for a a batch of
+# `.swift` source files in a module.
+SWIFT_ACTION_COMPILE_CODEGEN = "SwiftCompileCodegen"
+
+# Compiles one or more `.swift` source files into a `.swiftmodule`.
+SWIFT_ACTION_COMPILE_MODULE = "SwiftCompileModule"
+
# Compiles a `.swiftinterface` file into a `.swiftmodule` file.
SWIFT_ACTION_COMPILE_MODULE_INTERFACE = "SwiftCompileModuleInterface"
@@ -54,6 +62,8 @@ def all_action_names():
return (
SWIFT_ACTION_AUTOLINK_EXTRACT,
SWIFT_ACTION_COMPILE,
+ SWIFT_ACTION_COMPILE_CODEGEN,
+ SWIFT_ACTION_COMPILE_MODULE,
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -67,5 +77,6 @@ def all_compile_action_names():
"""Returns all actions that compile source files."""
return [
SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
+ SWIFT_ACTION_COMPILE_CODEGEN,
+ SWIFT_ACTION_COMPILE_MODULE,
]
diff --git a/swift/internal/compiling.bzl b/swift/internal/compiling.bzl
index 5c23da2be..fd7b80af3 100644
--- a/swift/internal/compiling.bzl
+++ b/swift/internal/compiling.bzl
@@ -28,6 +28,8 @@ load(
load(
":action_names.bzl",
"SWIFT_ACTION_COMPILE",
+ "SWIFT_ACTION_COMPILE_CODEGEN",
+ "SWIFT_ACTION_COMPILE_MODULE",
"SWIFT_ACTION_COMPILE_MODULE_INTERFACE",
"SWIFT_ACTION_DERIVE_FILES",
"SWIFT_ACTION_DUMP_AST",
@@ -38,12 +40,14 @@ load(":explicit_module_map_file.bzl", "write_explicit_swift_module_map_file")
load(
":feature_names.bzl",
"SWIFT_FEATURE_ADD_TARGET_NAME_TO_OUTPUT",
+ "SWIFT_FEATURE_COMPILE_IN_PARALLEL",
"SWIFT_FEATURE_DECLARE_SWIFTSOURCEINFO",
"SWIFT_FEATURE_EMIT_BC",
"SWIFT_FEATURE_EMIT_C_MODULE",
"SWIFT_FEATURE_EMIT_PRIVATE_SWIFTINTERFACE",
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_EMIT_SWIFTINTERFACE",
+ "SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION",
"SWIFT_FEATURE_FULL_LTO",
"SWIFT_FEATURE_HEADERS_ALWAYS_ACTION_INPUTS",
"SWIFT_FEATURE_INDEX_WHILE_BUILDING",
@@ -51,6 +55,7 @@ load(
"SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD",
"SWIFT_FEATURE_NO_GENERATED_MODULE_MAP",
"SWIFT_FEATURE_OPT",
+ "SWIFT_FEATURE_OPT_USES_CMO",
"SWIFT_FEATURE_OPT_USES_WMO",
"SWIFT_FEATURE_PROPAGATE_GENERATED_MODULE_MAP",
"SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION",
@@ -59,6 +64,7 @@ load(
"SWIFT_FEATURE_USE_EXPLICIT_SWIFT_MODULE_MAP",
"SWIFT_FEATURE_VFSOVERLAY",
"SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS",
+ "SWIFT_FEATURE__OPT_IN_SWIFTCOPTS",
"SWIFT_FEATURE__WMO_IN_SWIFTCOPTS",
)
load(
@@ -69,6 +75,12 @@ load(
"upcoming_and_experimental_features",
)
load(":module_maps.bzl", "write_module_map")
+load(
+ ":optimization.bzl",
+ "find_num_threads_flag_value",
+ "is_optimization_manually_requested",
+ "is_wmo_manually_requested",
+)
load(":toolchain_utils.bzl", "SWIFT_TOOLCHAIN_TYPE")
load(
":utils.bzl",
@@ -81,7 +93,6 @@ load(
"struct_fields",
)
load(":vfsoverlay.bzl", "write_vfsoverlay")
-load(":wmo.bzl", "find_num_threads_flag_value", "is_wmo_manually_requested")
# VFS root where all .swiftmodule files will be placed when
# SWIFT_FEATURE_VFSOVERLAY is enabled.
@@ -455,18 +466,6 @@ def compile(
else:
original_module_name = None
- # Collect the `SwiftInfo` providers that represent the dependencies of the
- # Objective-C generated header module -- this includes the dependencies of
- # the Swift module, plus any additional dependencies that the toolchain says
- # are required for all generated header modules. These are used immediately
- # below to write the module map for the header's module (to provide the
- # `use` declarations), and later in this function when precompiling the
- # module.
- generated_module_deps_swift_infos = (
- swift_infos +
- swift_toolchain.generated_header_module_implicit_deps_providers.swift_infos
- )
-
# These are the `SwiftInfo` providers that will be merged with the compiled
# module context and returned as the `swift_info` field of this function's
# result. Note that private deps are explicitly not included here, as they
@@ -501,56 +500,17 @@ def compile(
const_gather_protocols_file = swift_toolchain.const_protocols_to_gather
- compile_outputs = _declare_compile_outputs(
+ compile_plan = _construct_compile_plan(
srcs = srcs,
actions = actions,
extract_const_values = bool(const_gather_protocols_file),
feature_configuration = feature_configuration,
generated_header_name = generated_header_name,
- generated_module_deps_swift_infos = generated_module_deps_swift_infos,
module_name = module_name,
target_name = target_name,
user_compile_flags = copts,
)
-
- split_derived_file_generation = is_feature_enabled(
- feature_configuration = feature_configuration,
- feature_name = SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION,
- )
-
- if split_derived_file_generation:
- all_compile_outputs = compact([
- compile_outputs.swiftinterface_file,
- compile_outputs.private_swiftinterface_file,
- compile_outputs.indexstore_directory,
- compile_outputs.macro_expansion_directory,
- ]) + compile_outputs.object_files + compile_outputs.const_values_files
- all_derived_outputs = compact([
- # The `.swiftmodule` file is explicitly listed as the first output
- # because it will always exist and because Bazel uses it as a key for
- # various things (such as the filename prefix for param files generated
- # for that action). This guarantees some predictability.
- compile_outputs.swiftmodule_file,
- compile_outputs.swiftdoc_file,
- compile_outputs.swiftsourceinfo_file,
- compile_outputs.generated_header_file,
- ])
- else:
- all_compile_outputs = compact([
- # The `.swiftmodule` file is explicitly listed as the first output
- # because it will always exist and because Bazel uses it as a key for
- # various things (such as the filename prefix for param files generated
- # for that action). This guarantees some predictability.
- compile_outputs.swiftmodule_file,
- compile_outputs.swiftdoc_file,
- compile_outputs.swiftinterface_file,
- compile_outputs.private_swiftinterface_file,
- compile_outputs.swiftsourceinfo_file,
- compile_outputs.generated_header_file,
- compile_outputs.indexstore_directory,
- compile_outputs.macro_expansion_directory,
- ]) + compile_outputs.object_files + compile_outputs.const_values_files
- all_derived_outputs = []
+ compile_outputs = compile_plan.outputs
# In `upstream` they call `merge_compilation_contexts` on passed in
# `compilation_contexts` instead of merging `CcInfo`s. This is because
@@ -647,64 +607,61 @@ to use swift_common.compile(include_dev_srch_paths = ...) instead.\
upcoming_features, experimental_features = upcoming_and_experimental_features(
feature_configuration = feature_configuration,
)
- prerequisites = struct(
- additional_inputs = additional_inputs,
- always_include_headers = is_feature_enabled(
+ prerequisites = {
+ "additional_inputs": additional_inputs,
+ "always_include_headers": is_feature_enabled(
feature_configuration = feature_configuration,
feature_name = SWIFT_FEATURE_HEADERS_ALWAYS_ACTION_INPUTS,
),
- bin_dir = feature_configuration._bin_dir,
- cc_compilation_context = merged_cc_info.compilation_context,
- const_gather_protocols_file = const_gather_protocols_file,
- cc_linking_context = merged_cc_info.linking_context,
- defines = sets.to_list(defines_set),
- developer_dirs = swift_toolchain.developer_dirs,
- experimental_features = experimental_features,
- explicit_swift_module_map_file = explicit_swift_module_map_file,
- genfiles_dir = feature_configuration._genfiles_dir,
- include_dev_srch_paths = include_dev_srch_paths_value,
- is_swift = True,
- module_name = module_name,
- original_module_name = original_module_name,
- package_name = package_name,
- plugins = collections.uniq(used_plugins),
- source_files = srcs,
- target_label = feature_configuration._label,
- transitive_modules = transitive_modules,
- transitive_swiftmodules = transitive_swiftmodules,
- upcoming_features = upcoming_features,
+ "bin_dir": feature_configuration._bin_dir,
+ "cc_compilation_context": merged_cc_info.compilation_context,
+ "const_gather_protocols_file": const_gather_protocols_file,
+ "cc_linking_context": merged_cc_info.linking_context,
+ "defines": sets.to_list(defines_set),
+ "developer_dirs": swift_toolchain.developer_dirs,
+ "experimental_features": experimental_features,
+ "explicit_swift_module_map_file": explicit_swift_module_map_file,
+ "genfiles_dir": feature_configuration._genfiles_dir,
+ "include_dev_srch_paths": include_dev_srch_paths_value,
+ "is_swift": True,
+ "module_name": module_name,
+ "original_module_name": original_module_name,
+ "package_name": package_name,
+ "plugins": collections.uniq(used_plugins),
+ "source_files": srcs,
+ "target_label": feature_configuration._label,
+ "transitive_modules": transitive_modules,
+ "transitive_swiftmodules": transitive_swiftmodules,
+ "upcoming_features": upcoming_features,
+ "user_compile_flags": copts,
+ "vfsoverlay_file": vfsoverlay_file,
+ "vfsoverlay_search_path": _SWIFTMODULES_VFS_ROOT,
+ "workspace_name": workspace_name,
+ } | struct_fields(compile_outputs)
+
+ if _should_plan_parallel_compilation(
+ feature_configuration = feature_configuration,
user_compile_flags = copts,
- vfsoverlay_file = vfsoverlay_file,
- vfsoverlay_search_path = _SWIFTMODULES_VFS_ROOT,
- workspace_name = workspace_name,
- # Merge the compile outputs into the prerequisites.
- **struct_fields(compile_outputs)
- )
-
- if split_derived_file_generation:
- run_toolchain_action(
+ ):
+ _execute_compile_plan(
actions = actions,
- action_name = SWIFT_ACTION_DERIVE_FILES,
+ compile_plan = compile_plan,
+ exec_group = exec_group,
+ feature_configuration = feature_configuration,
+ prerequisites = prerequisites,
+ swift_toolchain = swift_toolchain,
+ toolchain_type = toolchain_type,
+ )
+ else:
+ _plan_legacy_swift_compilation(
+ actions = actions,
+ compile_outputs = compile_plan.outputs,
exec_group = exec_group,
feature_configuration = feature_configuration,
- outputs = all_derived_outputs,
prerequisites = prerequisites,
- progress_message = "Generating derived files for Swift module %{label}",
swift_toolchain = swift_toolchain,
toolchain_type = toolchain_type,
)
-
- run_toolchain_action(
- actions = actions,
- action_name = SWIFT_ACTION_COMPILE,
- exec_group = exec_group,
- feature_configuration = feature_configuration,
- outputs = all_compile_outputs,
- prerequisites = prerequisites,
- progress_message = "Compiling Swift module %{label}",
- swift_toolchain = swift_toolchain,
- toolchain_type = toolchain_type,
- )
# Dump AST has to run in its own action because `-dump-ast` is incompatible
# with emitting dependency files, which compile/derive files use when
@@ -718,71 +675,40 @@ to use swift_common.compile(include_dev_srch_paths = ...) instead.\
exec_group = exec_group,
feature_configuration = feature_configuration,
outputs = compile_outputs.ast_files,
- prerequisites = prerequisites,
+ prerequisites = struct(**prerequisites),
progress_message = "Dumping Swift AST for %{label}",
swift_toolchain = swift_toolchain,
toolchain_type = toolchain_type,
)
- # If a header and module map were generated for this Swift module, attempt
- # to precompile the explicit module for that header as well.
- if generated_header_name and not is_feature_enabled(
- feature_configuration = feature_configuration,
- feature_name = SWIFT_FEATURE_NO_GENERATED_MODULE_MAP,
- ):
- compilation_context_to_compile = (
- compilation_context_for_explicit_module_compilation(
- compilation_contexts = [
- cc_common.create_compilation_context(
- headers = depset([
- compile_outputs.generated_header_file,
- ]),
- ),
- merged_cc_info.compilation_context,
- ],
- swift_infos = swift_infos,
- )
- )
-
- pcm_outputs = _precompile_clang_module(
- actions = actions,
- cc_compilation_context = compilation_context_to_compile,
- exec_group = exec_group,
- feature_configuration = feature_configuration,
- is_swift_generated_header = True,
- module_map_file = compile_outputs.generated_module_map_file,
- module_name = module_name,
- swift_infos = generated_module_deps_swift_infos,
- swift_toolchain = swift_toolchain,
- target_name = target_name,
- toolchain_type = toolchain_type,
- )
- if pcm_outputs:
- precompiled_module = pcm_outputs.pcm_file
- else:
- precompiled_module = None
- else:
- precompiled_module = None
-
compilation_context = create_compilation_context(
defines = defines,
srcs = srcs,
transitive_modules = transitive_modules,
)
- if compile_outputs.generated_header_file:
- public_hdrs = [compile_outputs.generated_header_file]
- else:
- public_hdrs = []
+ merged_compilation_context = merge_compilation_contexts(
+ transitive_compilation_contexts = (
+ compilation_contexts + [
+ cc_info.compilation_context
+ for cc_info in swift_toolchain.implicit_deps_providers.cc_infos
+ ]
+ ),
+ )
- if compile_outputs.generated_module_map_file and is_feature_enabled(
+ generated_header_module = _compile_generated_header_clang_module(
+ actions = actions,
+ exec_group = exec_group,
feature_configuration = feature_configuration,
- feature_name = SWIFT_FEATURE_PROPAGATE_GENERATED_MODULE_MAP,
- ):
- public_hdrs.append(compile_outputs.generated_module_map_file)
- includes = [compile_outputs.generated_module_map_file.dirname]
- else:
- includes = []
+ generated_header_file = compile_outputs.generated_header_file,
+ generated_header_name = generated_header_name,
+ merged_compilation_context = merged_compilation_context,
+ module_name = module_name,
+ swift_infos = swift_infos,
+ swift_toolchain = swift_toolchain,
+ target_name = target_name,
+ toolchain_type = toolchain_type,
+ )
module_context = create_swift_module_context(
name = module_name,
@@ -792,13 +718,13 @@ to use swift_common.compile(include_dev_srch_paths = ...) instead.\
compilation_contexts = compilation_contexts,
defines = defines,
feature_configuration = feature_configuration,
- includes = includes,
- public_hdrs = public_hdrs,
+ includes = generated_header_module.includes,
+ public_hdrs = generated_header_module.public_hdrs,
swift_toolchain = swift_toolchain,
target_name = target_name,
),
- module_map = compile_outputs.generated_module_map_file,
- precompiled_module = precompiled_module,
+ module_map = generated_header_module.module_map_file,
+ precompiled_module = generated_header_module.precompiled_module,
),
compilation_context = compilation_context,
is_system = False,
@@ -838,6 +764,456 @@ to use swift_common.compile(include_dev_srch_paths = ...) instead.\
),
)
+def _should_plan_parallel_compilation(
+ feature_configuration,
+ user_compile_flags):
+ """Returns `True` if the compilation should be done in parallel."""
+ if not is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_COMPILE_IN_PARALLEL,
+ ):
+ return False
+
+ # TODO: are we able to support split derived file generation in parallel, this feature is not in upstream.
+ # For now, force non-parallel compilation when split derived file generation is enabled.
+ if is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION,
+ ):
+ return False
+
+ # When the Swift driver plans a compilation, the default behavior is to emit
+ # separate frontend jobs to emit the module and to perform codegen. However,
+ # this will *not* happen if cross-module optimization is possible; in that
+ # case, the driver emits a single frontend job to compile everything. If any
+ # of the following conditions is true, then cross-module optimization is not
+ # possible and we can plan parallel compilation:
+ #
+ # - Whole-module optimization is not enabled.
+ # - Library evolution is enabled.
+ # - Cross-module optimization has been explicitly disabled.
+ # - Optimization (via the `-O` flag group) has not been requested.
+ #
+ # This logic mirrors that defined in
+ # https://github.com/swiftlang/swift-driver/blob/c647e91574122f2b104d294ab1ec5baadaa1aa95/Sources/SwiftDriver/Jobs/EmitModuleJob.swift#L156-L181.
+ if not (
+ is_wmo_manually_requested(
+ user_compile_flags = user_compile_flags,
+ ) or are_all_features_enabled(
+ feature_configuration = feature_configuration,
+ feature_names = [SWIFT_FEATURE_OPT, SWIFT_FEATURE_OPT_USES_WMO],
+ ) or is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE__WMO_IN_SWIFTCOPTS,
+ )
+ ):
+ return True
+
+ if is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION,
+ ):
+ return True
+
+ if not is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_OPT_USES_CMO,
+ ):
+ return True
+
+ return (
+ not is_optimization_manually_requested(
+ user_compile_flags = user_compile_flags,
+ ) and not is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_OPT,
+ ) and not is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE__OPT_IN_SWIFTCOPTS,
+ )
+ )
+
+def _execute_compile_plan(
+ actions,
+ compile_plan,
+ exec_group,
+ feature_configuration,
+ prerequisites,
+ swift_toolchain,
+ toolchain_type):
+ """Executes the planned actions needed to compile a Swift module.
+
+ Args:
+ actions: The context's `actions` object.
+ compile_plan: A `struct` containing information about the planned
+ compilation actions.
+ exec_group: Runs the Swift compilation action under the given execution
+ group's context. If `None`, the default execution group is used.
+ feature_configuration: A feature configuration obtained from
+ `swift_common.configure_features`.
+ prerequisites: A `dict` containing the common prerequisites for the
+ compilation action.
+ swift_toolchain: The Swift toolchain being used to build.
+ toolchain_type: The toolchain type of the `swift_toolchain`.
+ """
+ compile_outputs = compile_plan.outputs
+ module_outputs = compact([
+ # We put the module file first so that any generated command line files
+ # will be named after it. This output will always exist so the names
+ # will be predictable.
+ compile_plan.module_outputs.swiftmodule_file,
+ compile_plan.module_outputs.generated_header_file,
+ compile_plan.module_outputs.macro_expansion_directory,
+ compile_plan.module_outputs.swiftdoc_file,
+ compile_plan.module_outputs.swiftinterface_file,
+ compile_plan.module_outputs.private_swiftinterface_file,
+ compile_plan.module_outputs.swiftsourceinfo_file,
+ ])
+
+ module_prereqs = dict(prerequisites)
+ module_prereqs["compile_step"] = struct(
+ action = SWIFT_ACTION_COMPILE_MODULE,
+ output = compile_outputs.swiftmodule_file.path,
+ )
+ run_toolchain_action(
+ actions = actions,
+ action_name = SWIFT_ACTION_COMPILE_MODULE,
+ exec_group = exec_group,
+ feature_configuration = feature_configuration,
+ outputs = module_outputs,
+ prerequisites = struct(**module_prereqs),
+ progress_message = "Compiling Swift module %{label}",
+ swift_toolchain = swift_toolchain,
+ toolchain_type = toolchain_type,
+ )
+
+ batches = _compute_codegen_batches(
+ batch_size = swift_toolchain.codegen_batch_size,
+ compile_plan = compile_plan,
+ feature_configuration = feature_configuration,
+ )
+ for number, batch in enumerate(batches, 1):
+ object_prereqs = dict(prerequisites)
+
+ # If there is only one batch (for small libraries, or libraries of any
+ # size compiled with whole-module optimization), we omit the requested
+ # file paths to eliminate some unneeded work in the worker. It will
+ # treat a blank value as "emit all outputs".
+ if len(batches) == 1:
+ step_detail = ""
+ else:
+ step_detail = ",".join([
+ object.path
+ for invocation in batch
+ for object in invocation.objects
+ ])
+ object_prereqs["compile_step"] = struct(
+ action = SWIFT_ACTION_COMPILE_CODEGEN,
+ output = step_detail,
+ )
+
+ batch_suffix = ""
+ if compile_plan.output_nature.emits_multiple_objects:
+ batch_suffix = " ({} of {})".format(number, len(batches))
+ progress_message = "Codegen for Swift module %{{label}}{}".format(
+ batch_suffix,
+ )
+
+ batch_outputs = [
+ output
+ for invocation in batch
+ for output in invocation.objects + invocation.other_outputs
+ ]
+ if is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_INDEX_WHILE_BUILDING,
+ ):
+ # TODO: b/351801556 - If this is true, then we only have one batch
+ # (`_compute_codegen_batches` ensures this). Indexing happens when
+ # object files are emitted, so we need to declare that output here.
+ # Update the APIs to support multiple indexstore directories per
+ # target so that we can emit one indexstore per batch instead.
+ batch_outputs.append(compile_plan.outputs.indexstore_directory)
+
+ run_toolchain_action(
+ actions = actions,
+ action_name = SWIFT_ACTION_COMPILE_CODEGEN,
+ exec_group = exec_group,
+ feature_configuration = feature_configuration,
+ outputs = batch_outputs,
+ prerequisites = struct(**object_prereqs),
+ progress_message = progress_message,
+ swift_toolchain = swift_toolchain,
+ toolchain_type = toolchain_type,
+ )
+
+def _compute_codegen_batches(
+ batch_size,
+ compile_plan,
+ feature_configuration):
+ """Computes the batches of object files that will be compiled.
+
+ Args:
+ batch_size: The number of source files to compile in each batch.
+ compile_plan: A `struct` containing information about the planned
+ compilation actions.
+ feature_configuration: The feature configuration for the target being
+ compiled.
+
+ Returns:
+ A list of batches. Each batch itself is a list, where each element is a
+ struct that specifies the outputs for a particular codegen invocation
+ to be registered.
+ """
+ codegen_outputs = compile_plan.codegen_outputs
+ codegen_count = len(codegen_outputs)
+
+ # TODO: b/351801556 - Update the APIs to support multiple indexstore
+ # directories per target so that we can emit one indexstore per batch. For
+ # now, force one batch if indexing is enabled.
+ if is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_INDEX_WHILE_BUILDING,
+ ):
+ return [codegen_outputs]
+
+ batch_count = codegen_count // batch_size
+
+ # Make sure to round up if we have a partial batch left over.
+ if codegen_count % batch_size != 0:
+ batch_count += 1
+
+ batches = []
+ for batch_index in range(batch_count):
+ batch_start = batch_index * batch_size
+ batch_end = min(batch_start + batch_size, codegen_count)
+ batches.append(codegen_outputs[batch_start:batch_end])
+ return batches
+
+def _plan_legacy_swift_compilation(
+ actions,
+ compile_outputs,
+ exec_group,
+ feature_configuration,
+ prerequisites,
+ swift_toolchain,
+ toolchain_type):
+ """Plans the single driver invocation needed to compile a Swift module.
+
+ The legacy compilation mode uses a single driver invocation to compile both
+ the `.swiftmodule` file and the object files.
+
+ Args:
+ actions: The context's `actions` object.
+ compile_outputs: A `struct` containing the registered outputs of the
+ compilation action.
+ exec_group: Runs the Swift compilation action under the given execution
+ group's context. If `None`, the default execution group is used.
+ feature_configuration: A feature configuration obtained from
+ `swift_common.configure_features`.
+ prerequisites: A `dict` containing the common prerequisites for the
+ compilation action.
+ swift_toolchain: The Swift toolchain being used to build.
+ toolchain_type: The toolchain type of the `swift_toolchain`.
+ """
+
+ split_derived_file_generation = is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION,
+ )
+
+ all_derived_outputs = []
+ if split_derived_file_generation:
+ all_compile_outputs = compact([
+ compile_outputs.swiftinterface_file,
+ compile_outputs.private_swiftinterface_file,
+ compile_outputs.indexstore_directory,
+ compile_outputs.macro_expansion_directory,
+ ]) + compile_outputs.object_files + compile_outputs.const_values_files
+ all_derived_outputs = compact([
+ # The `.swiftmodule` file is explicitly listed as the first output
+ # because it will always exist and because Bazel uses it as a key for
+ # various things (such as the filename prefix for param files generated
+ # for that action). This guarantees some predictability.
+ compile_outputs.swiftmodule_file,
+ compile_outputs.swiftdoc_file,
+ compile_outputs.swiftsourceinfo_file,
+ compile_outputs.generated_header_file,
+ ])
+ else:
+ all_compile_outputs = compact([
+ # The `.swiftmodule` file is explicitly listed as the first output
+ # because it will always exist and because Bazel uses it as a key for
+ # various things (such as the filename prefix for param files generated
+ # for that action). This guarantees some predictability.
+ compile_outputs.swiftmodule_file,
+ compile_outputs.swiftdoc_file,
+ compile_outputs.swiftinterface_file,
+ compile_outputs.private_swiftinterface_file,
+ compile_outputs.swiftsourceinfo_file,
+ compile_outputs.generated_header_file,
+ compile_outputs.indexstore_directory,
+ compile_outputs.macro_expansion_directory,
+ ]) + compile_outputs.object_files + compile_outputs.const_values_files
+
+ if split_derived_file_generation:
+ run_toolchain_action(
+ actions = actions,
+ action_name = SWIFT_ACTION_DERIVE_FILES,
+ exec_group = exec_group,
+ feature_configuration = feature_configuration,
+ outputs = all_derived_outputs,
+ prerequisites = struct(**prerequisites),
+ progress_message = "Generating derived files for Swift module %{label}",
+ swift_toolchain = swift_toolchain,
+ toolchain_type = toolchain_type,
+ )
+
+ run_toolchain_action(
+ actions = actions,
+ action_name = SWIFT_ACTION_COMPILE,
+ exec_group = exec_group,
+ feature_configuration = feature_configuration,
+ outputs = all_compile_outputs,
+ prerequisites = struct(**prerequisites),
+ progress_message = "Compiling Swift module %{label}",
+ swift_toolchain = swift_toolchain,
+ toolchain_type = toolchain_type,
+ )
+
+def _compile_generated_header_clang_module(
+ actions,
+ exec_group,
+ feature_configuration,
+ generated_header_file,
+ generated_header_name,
+ merged_compilation_context,
+ module_name,
+ swift_infos,
+ swift_toolchain,
+ target_name,
+ toolchain_type):
+ """Precompiles the Clang module for a Swift module's generated header.
+
+ Args:
+
+ Returns:
+ A `struct` (never `None`) containing the following fields:
+
+ * `module_map_file`: The module map file that defines the Clang module
+ for the Swift generated header. This may be `None` if the
+ `swift.no_generated_module_map` feature is enabled.
+ * `precompiled_module`: The precompiled module that contains the
+ compiled Clang module. This may be `None` if explicit modules are
+ not enabled.
+ """
+
+ # If no generated header and not generating a module map, nothing to do.
+ if not generated_header_name and is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_NO_GENERATED_MODULE_MAP,
+ ):
+ return struct(
+ module_map_file = None,
+ precompiled_module = None,
+ includes = [],
+ public_hdrs = [],
+ )
+
+ # Collect the `SwiftInfo` providers that represent the dependencies of the
+ # Objective-C generated header module -- this includes the dependencies of
+ # the Swift module, plus any additional dependencies that the toolchain says
+ # are required for all generated header modules.
+ generated_module_deps_swift_infos = (
+ swift_infos +
+ swift_toolchain.generated_header_module_implicit_deps_providers.swift_infos
+ )
+ dependent_module_names = sets.make()
+ for swift_info in generated_module_deps_swift_infos:
+ for module in swift_info.direct_modules:
+ if module.clang:
+ sets.insert(dependent_module_names, module.name)
+
+ # Create a module map for the generated header file. This ensures that
+ # inclusions of it are treated modularly, not textually.
+ #
+ # Caveat: Generated module maps are incompatible with the hack that some
+ # folks are using to support mixed Objective-C and Swift modules. This trap
+ # door lets them escape the module redefinition error, with the caveat that
+ # that certain import scenarios could lead to incorrect behavior because a
+ # header can be imported textually instead of modularly.
+ if generated_header_file and not is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_NO_GENERATED_MODULE_MAP,
+ ):
+ generated_module_map = actions.declare_file(
+ "{}_modulemap/_/module.modulemap".format(target_name),
+ )
+ write_module_map(
+ actions = actions,
+ dependent_module_names = sorted(sets.to_list(dependent_module_names)),
+ module_map_file = generated_module_map,
+ module_name = module_name,
+ public_headers = [generated_header_file],
+ workspace_relative = is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD,
+ ),
+ )
+
+ compilation_context_to_compile = (
+ compilation_context_for_explicit_module_compilation(
+ compilation_contexts = [
+ cc_common.create_compilation_context(
+ headers = depset([generated_header_file]),
+ ),
+ merged_compilation_context,
+ ],
+ swift_infos = swift_infos,
+ )
+ )
+ pcm_outputs = _precompile_clang_module(
+ actions = actions,
+ cc_compilation_context = compilation_context_to_compile,
+ exec_group = exec_group,
+ feature_configuration = feature_configuration,
+ is_swift_generated_header = True,
+ module_map_file = generated_module_map,
+ module_name = module_name,
+ swift_infos = generated_module_deps_swift_infos,
+ swift_toolchain = swift_toolchain,
+ target_name = target_name,
+ toolchain_type = toolchain_type,
+ )
+ if pcm_outputs:
+ precompiled_module = pcm_outputs.pcm_file
+ else:
+ precompiled_module = None
+ else:
+ generated_module_map = None
+ precompiled_module = None
+
+ if generated_header_file:
+ public_hdrs = [generated_header_file]
+ else:
+ public_hdrs = []
+
+ if generated_module_map and is_feature_enabled(
+ feature_configuration = feature_configuration,
+ feature_name = SWIFT_FEATURE_PROPAGATE_GENERATED_MODULE_MAP,
+ ):
+ public_hdrs.append(generated_module_map)
+ includes = [generated_module_map.dirname]
+ else:
+ includes = []
+
+ return struct(
+ module_map_file = generated_module_map,
+ precompiled_module = precompiled_module,
+ includes = includes,
+ public_hdrs = public_hdrs,
+ )
+
def precompile_clang_module(
*,
actions,
@@ -1156,13 +1532,12 @@ def _cross_imported_swift_infos(*, swift_toolchain, user_swift_infos):
return overlay_swift_infos
-def _declare_compile_outputs(
+def _construct_compile_plan(
*,
actions,
extract_const_values,
feature_configuration,
generated_header_name,
- generated_module_deps_swift_infos,
module_name,
srcs,
target_name,
@@ -1177,9 +1552,6 @@ def _declare_compile_outputs(
`configure_features`.
generated_header_name: The desired name of the generated header for this
module, or `None` if no header should be generated.
- generated_module_deps_swift_infos: `SwiftInfo` providers from
- dependencies of the module for the generated header of the target
- being compiled.
module_name: The name of the Swift module being compiled.
srcs: The list of source files that will be compiled.
target_name: The name (excluding package path) of the target being
@@ -1271,45 +1643,6 @@ def _declare_compile_outputs(
else:
generated_header = None
- # If not disabled, create a module map for the generated header file. This
- # ensures that inclusions of it are treated modularly, not textually.
- #
- # Caveat: Generated module maps are incompatible with the hack that some
- # folks are using to support mixed Objective-C and Swift modules. This
- # trap door lets them escape the module redefinition error, with the
- # caveat that certain import scenarios could lead to incorrect behavior
- # because a header can be imported textually instead of modularly.
- if generated_header and not is_feature_enabled(
- feature_configuration = feature_configuration,
- feature_name = SWIFT_FEATURE_NO_GENERATED_MODULE_MAP,
- ):
- # Collect the names of Clang modules that the module being built
- # directly depends on.
- dependent_module_names = sets.make()
- for swift_info in generated_module_deps_swift_infos:
- for module in swift_info.direct_modules:
- if module.clang:
- sets.insert(dependent_module_names, module.name)
-
- generated_module_map = actions.declare_file(
- "{}_modulemap/_/module.modulemap".format(target_name),
- )
- write_module_map(
- actions = actions,
- dependent_module_names = sorted(
- sets.to_list(dependent_module_names),
- ),
- module_map_file = generated_module_map,
- module_name = module_name,
- public_headers = [generated_header],
- workspace_relative = is_feature_enabled(
- feature_configuration = feature_configuration,
- feature_name = SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD,
- ),
- )
- else:
- generated_module_map = None
-
# Now, declare outputs like object files for which there may be one or many,
# depending on the compilation mode.
output_nature = _emitted_output_nature(
@@ -1357,6 +1690,10 @@ def _declare_compile_outputs(
]
output_file_map = None
derived_files_output_file_map = None
+ codegen_outputs = [struct(
+ objects = object_files,
+ other_outputs = const_values_files,
+ )]
# TODO(b/147451378): Support indexing even with a single object file.
else:
@@ -1401,6 +1738,7 @@ def _declare_compile_outputs(
const_values_files = output_info.const_values_files
output_file_map = output_info.output_file_map
derived_files_output_file_map = output_info.derived_files_output_file_map
+ codegen_outputs = output_info.codegen_outputs
if not is_feature_enabled(
feature_configuration = feature_configuration,
@@ -1416,7 +1754,6 @@ def _declare_compile_outputs(
ast_files = ast_files,
const_values_files = const_values_files,
generated_header_file = generated_header,
- generated_module_map_file = generated_module_map,
indexstore_directory = indexstore_directory,
macro_expansion_directory = macro_expansion_directory,
private_swiftinterface_file = private_swiftinterface_file,
@@ -1428,7 +1765,26 @@ def _declare_compile_outputs(
swiftmodule_file = swiftmodule_file,
swiftsourceinfo_file = swiftsourceinfo_file,
)
- return compile_outputs
+
+ return struct(
+ codegen_outputs = codegen_outputs,
+ module_outputs = struct(
+ generated_header_file = generated_header,
+ # TODO: b/351801556 - Verify that this is correct; it may need to be
+ # done by the codegen actions.
+ macro_expansion_directory = macro_expansion_directory,
+ swiftdoc_file = swiftdoc_file,
+ swiftinterface_file = swiftinterface_file,
+ private_swiftinterface_file = private_swiftinterface_file,
+ swiftmodule_file = swiftmodule_file,
+ swiftsourceinfo_file = swiftsourceinfo_file,
+ ),
+ output_file_map = output_file_map,
+ output_nature = output_nature,
+ # TODO: b/351801556 - Migrate all the action configuration logic off
+ # this legacy structure.
+ outputs = compile_outputs,
+ )
def _declare_per_source_output_file(actions, extension, target_name, src):
"""Declares a file for a per-source output file during compilation.
@@ -1501,6 +1857,14 @@ def _declare_multiple_outputs_and_write_output_file_map(
"{}.output_file_map.json".format(target_name),
)
+ # Collect the outputs that are expected to be produced by codegen actions.
+ # In a WMO build, all object files (and related codegen outputs, like
+ # const-values files) are emitted by a single frontend action, *regardless*
+ # of whether the compilation is multi-threaded (i.e., produces multiple
+ # outputs) or not. In a non-WMO build, there will be one frontend action
+ # per source file.
+ codegen_outputs = []
+
if split_derived_file_generation:
derived_files_output_map_file = actions.declare_file(
"{}.derived_output_file_map.json".format(target_name),
@@ -1518,13 +1882,6 @@ def _declare_multiple_outputs_and_write_output_file_map(
output_objs = []
const_values_files = []
- if extract_const_values and is_wmo:
- const_values_file = actions.declare_file(
- "{}.swiftconstvalues".format(target_name),
- )
- const_values_files.append(const_values_file)
- whole_module_map["const-values"] = const_values_file.path
-
for src in srcs:
file_outputs = {}
@@ -1561,18 +1918,38 @@ def _declare_multiple_outputs_and_write_output_file_map(
if include_index_unit_paths:
file_outputs["index-unit-output-path"] = obj.path
- if extract_const_values and not is_wmo:
- const_values_file = _declare_per_source_output_file(
- actions = actions,
- extension = "swiftconstvalues",
- target_name = target_name,
- src = src,
- )
- const_values_files.append(const_values_file)
- file_outputs["const-values"] = const_values_file.path
+ if not is_wmo:
+ const_values_file = None
+ if extract_const_values:
+ const_values_file = _declare_per_source_output_file(
+ actions = actions,
+ extension = "swiftconstvalues",
+ target_name = target_name,
+ src = src,
+ )
+ const_values_files.append(const_values_file)
+ file_outputs["const-values"] = const_values_file.path
+
+ codegen_outputs.append(struct(
+ objects = [obj],
+ other_outputs = compact([const_values_file]),
+ ))
output_map[src.path] = file_outputs
+ if is_wmo:
+ if extract_const_values:
+ const_value_file = actions.declare_file(
+ "{}.swiftconstvalues".format(target_name),
+ )
+ const_values_files.append(const_value_file)
+ whole_module_map["const-values"] = const_value_file.path
+
+ codegen_outputs.append(struct(
+ objects = output_objs,
+ other_outputs = const_values_files,
+ ))
+
if whole_module_map:
output_map[""] = whole_module_map
@@ -1589,6 +1966,7 @@ def _declare_multiple_outputs_and_write_output_file_map(
return struct(
ast_files = ast_files,
+ codegen_outputs = codegen_outputs,
const_values_files = const_values_files,
derived_files_output_file_map = derived_files_output_map_file,
object_files = output_objs,
diff --git a/swift/internal/feature_names.bzl b/swift/internal/feature_names.bzl
index 3242857a4..dd68d4d70 100644
--- a/swift/internal/feature_names.bzl
+++ b/swift/internal/feature_names.bzl
@@ -173,6 +173,15 @@ SWIFT_FEATURE_OPT_USES_WMO = "swift.opt_uses_wmo"
# the `-Osize` flag instead of `-O`.
SWIFT_FEATURE_OPT_USES_OSIZE = "swift.opt_uses_osize"
+# If enabled, compilations that are using whole-module optimization and also
+# request optimizations via the `-O` flag group will have cross-module
+# optimization performed. This is the default behavior for the Swift compiler
+# and for these build rules, with one exception: because CMO prevents
+# parallelized compilation, we unconditionally disable CMO for targets built in
+# an `exec` configuration under the presumption that build speed is more
+# important than runtime performance for build tools.
+SWIFT_FEATURE_OPT_USES_CMO = "swift.opt_uses_cmo"
+
# If enabled, and if the toolchain specifies a generated header rewriting tool,
# that tool will be invoked after compilation to rewrite the generated header in
# place.
@@ -347,6 +356,11 @@ SWIFT_FEATURE_LLD_GC_WORKAROUND = "swift.lld_gc_workaround"
# objects if you know that isn't required.
SWIFT_FEATURE_OBJC_LINK_FLAGS = "swift.objc_link_flag"
+# A private feature that is set by the toolchain if an optimization flag in the
+# `-O` flag group was passed on the command line using `--swiftcopt`. Users
+# should never manually enable, disable, or query this feature.
+SWIFT_FEATURE__OPT_IN_SWIFTCOPTS = "swift._opt_in_swiftcopts"
+
# If enabled, requests the `-enforce-exclusivity=checked` swiftc flag which
# enables runtime checking of exclusive memory access on mutation.
SWIFT_FEATURE_CHECKED_EXCLUSIVITY = "swift.checked_exclusivity"
@@ -369,6 +383,10 @@ SWIFT_FEATURE_INTERNALIZE_AT_LINK = "swift.internalize_at_link"
# This disables checking for potentially unavailable APIs.
SWIFT_FEATURE_DISABLE_AVAILABILITY_CHECKING = "swift.disable_availability_checking"
+# If enabled, parallelize the compilation of Swift modules and their object
+# files by registering separate actions for each.
+SWIFT_FEATURE_COMPILE_IN_PARALLEL = "swift.compile_in_parallel"
+
# A private feature that is set by the toolchain if it supports the
# `-enable-{experimental,upcoming}-feature` flag (Swift 5.8 and above). Users
# should never manually, enable, disable, or query this feature.
diff --git a/swift/internal/features.bzl b/swift/internal/features.bzl
index f088815e6..14182f0ae 100644
--- a/swift/internal/features.bzl
+++ b/swift/internal/features.bzl
@@ -36,6 +36,7 @@ load(
"SWIFT_FEATURE_INTERNALIZE_AT_LINK",
"SWIFT_FEATURE_NO_GENERATED_MODULE_MAP",
"SWIFT_FEATURE_OBJC_LINK_FLAGS",
+ "SWIFT_FEATURE_OPT_USES_CMO",
"SWIFT_FEATURE_OPT_USES_WMO",
"SWIFT_FEATURE_REMAP_XCODE_PATH",
"SWIFT_FEATURE_USE_GLOBAL_MODULE_CACHE",
@@ -136,6 +137,19 @@ def configure_features(
unsupported_features = unsupported_features,
)
+ # Disable CMO for builds in `exec` configurations so that we can use
+ # parallelized compilation for build tools written in Swift. The speedup
+ # from parallelized compilation is significantly higher than the performance
+ # loss from disabling CMO.
+ #
+ # HACK: There is no supported API yet to detect whether a build is in an
+ # `exec` configuration. https://github.com/bazelbuild/bazel/issues/14444.
+ if "-exec" in ctx.bin_dir.path or "/host/" in ctx.bin_dir.path:
+ unsupported_features.append(SWIFT_FEATURE_OPT_USES_CMO)
+ else:
+ requested_features = list(requested_features)
+ requested_features.append(SWIFT_FEATURE_OPT_USES_CMO)
+
all_requestable_features, all_unsupported_features = _compute_features(
label = ctx.label,
requested_features = requested_features,
@@ -149,6 +163,7 @@ def configure_features(
requested_features = all_requestable_features,
unsupported_features = all_unsupported_features,
)
+
return struct(
_cc_feature_configuration = cc_feature_configuration,
_enabled_features = all_requestable_features,
@@ -169,7 +184,7 @@ def configure_features(
)
def features_for_build_modes(ctx, cpp_fragment = None):
- """Returns a list of Swift toolchain features for current build modes.
+ """Returns features to request and disable for current build modes.
This function explicitly breaks the "don't pass `ctx` as an argument"
rule-of-thumb because it is internal and only called from the toolchain
@@ -177,19 +192,29 @@ def features_for_build_modes(ctx, cpp_fragment = None):
Args:
ctx: The current rule context.
- cpp_fragment: The Cpp configuration fragment, if available.
+ cpp_fragment: The `cpp` configuration fragment, if available.
Returns:
- A list of Swift toolchain features to enable.
+ A tuple containing two lists:
+
+ 1. A list of Swift toolchain features to requested (enable).
+ 2. A list of Swift toolchain features that are unsupported (disabled).
"""
+ requested_features = []
+ unsupported_features = []
+
compilation_mode = ctx.var["COMPILATION_MODE"]
- features = []
- features.append("swift.{}".format(compilation_mode))
+ requested_features.append("swift.{}".format(compilation_mode))
if compilation_mode in ("dbg", "fastbuild"):
- features.append(SWIFT_FEATURE_ENABLE_TESTING)
+ requested_features.append(SWIFT_FEATURE_ENABLE_TESTING)
+
+ if ctx.configuration.coverage_enabled:
+ requested_features.append(SWIFT_FEATURE_COVERAGE)
+
if cpp_fragment and cpp_fragment.apple_generate_dsym:
- features.append(SWIFT_FEATURE_FULL_DEBUG_INFO)
- return features
+ requested_features.append(SWIFT_FEATURE_FULL_DEBUG_INFO)
+
+ return requested_features, unsupported_features
def get_cc_feature_configuration(feature_configuration):
"""Returns the C++ feature configuration in a Swift feature configuration.
diff --git a/swift/internal/wmo.bzl b/swift/internal/optimization.bzl
similarity index 69%
rename from swift/internal/wmo.bzl
rename to swift/internal/optimization.bzl
index 50fc8b272..fbca8001f 100644
--- a/swift/internal/wmo.bzl
+++ b/swift/internal/optimization.bzl
@@ -12,11 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-"""Functionality releated to detecting whole-module optimization."""
+"""Detection of various optimization settings."""
load(
":feature_names.bzl",
"SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS",
+ "SWIFT_FEATURE__OPT_IN_SWIFTCOPTS",
"SWIFT_FEATURE__WMO_IN_SWIFTCOPTS",
)
@@ -28,29 +29,14 @@ _WMO_FLAGS = {
"-force-single-frontend-invocation": True,
}
-def features_from_swiftcopts(swiftcopts):
- """Returns a list of features to enable based on `--swiftcopt` flags.
-
- Since `--swiftcopt` flags are hooked into the action configuration when the
- toolchain is configured, it's not possible for individual actions to query
- them easily if those flags may determine the nature of outputs (for example,
- single- vs. multi-threaded WMO). The toolchain can call this function to map
- those flags to private features that can be queried instead.
-
- Args:
- swiftcopts: The list of command line flags that were passed using
- `--swiftcopt`.
-
- Returns:
- A list (possibly empty) of strings denoting feature names that should be
- enabled on the toolchain.
- """
- features = []
- if is_wmo_manually_requested(user_compile_flags = swiftcopts):
- features.append(SWIFT_FEATURE__WMO_IN_SWIFTCOPTS)
- if find_num_threads_flag_value(user_compile_flags = swiftcopts) == 0:
- features.append(SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS)
- return features
+# Swift command line flags in the `O` group that enable some kind of
+# optimization. This explicitly excludes `-Onone`.
+_OPT_FLAGS = {
+ "-O": True,
+ "-Oplayground": True,
+ "-Osize": True,
+ "-Ounchecked": True,
+}
def find_num_threads_flag_value(user_compile_flags):
"""Finds the value of the `-num-threads` flag.
@@ -75,6 +61,20 @@ def find_num_threads_flag_value(user_compile_flags):
saw_num_threads = True
return num_threads
+def is_optimization_manually_requested(user_compile_flags):
+ """Returns `True` if some optimization flag is in the given list of flags.
+
+ Args:
+ user_compile_flags: A list of compiler flags to scan for optimization.
+
+ Returns:
+ True if some optimization is enabled in the given list of flags.
+ """
+ for copt in user_compile_flags:
+ if copt in _OPT_FLAGS:
+ return True
+ return False
+
def is_wmo_manually_requested(user_compile_flags):
"""Returns `True` if a WMO flag is in the given list of compiler flags.
@@ -89,8 +89,8 @@ def is_wmo_manually_requested(user_compile_flags):
return True
return False
-def wmo_features_from_swiftcopts(swiftcopts):
- """Returns a list of features to enable based on `--swiftcopt` flags.
+def optimization_features_from_swiftcopts(swiftcopts):
+ """Returns features to enable or disable based on `--swiftcopt` flags.
Since `--swiftcopt` flags are hooked into the action configuration when the
toolchain is configured, it's not possible for individual actions to query
@@ -103,15 +103,24 @@ def wmo_features_from_swiftcopts(swiftcopts):
`--swiftcopt`.
Returns:
- A list (possibly empty) of strings denoting feature names that should be
- enabled on the toolchain.
+ A tuple containing two lists:
+
+ 1. A list (possibly empty) of strings denoting feature names that
+ should be enabled on the toolchain.
+ 2. A list (possibly empty) of strings denoting feature names that
+ should be disabled on the toolchain.
"""
- features = []
+ requested_features = []
+ unsupported_features = []
+
+ if is_optimization_manually_requested(user_compile_flags = swiftcopts):
+ requested_features.append(SWIFT_FEATURE__OPT_IN_SWIFTCOPTS)
if is_wmo_manually_requested(user_compile_flags = swiftcopts):
- features.append(SWIFT_FEATURE__WMO_IN_SWIFTCOPTS)
+ requested_features.append(SWIFT_FEATURE__WMO_IN_SWIFTCOPTS)
if find_num_threads_flag_value(user_compile_flags = swiftcopts) == 1:
- features.append(SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS)
- return features
+ requested_features.append(SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS)
+
+ return requested_features, unsupported_features
def _safe_int(s):
"""Returns the base-10 integer value of `s` or `None` if it is invalid.
diff --git a/swift/providers.bzl b/swift/providers.bzl
index f7ab88f9e..d0006fb09 100644
--- a/swift/providers.bzl
+++ b/swift/providers.bzl
@@ -336,6 +336,10 @@ C/Objective-C modules:
For ease of use, this field is never `None`; it will always be a valid `struct`
containing the fields described above, even if those lists are empty.
+""",
+ "codegen_batch_size": """\
+The number of files to pass to the compiler in a single code generation action
+(one that compiles object files from Swift source files).
""",
"const_protocols_to_gather": """\
`File`. A JSON file specifying a list of protocols for extraction of
@@ -442,9 +446,7 @@ Swift build rules, and they are also passed to the C++ APIs used when linking
`String`. The workspace-relative root directory of the toolchain.
""",
"swift_worker": """\
-`File`. The executable representing the worker executable used to invoke the
-compiler and other Swift tools (for both incremental and non-incremental
-compiles).
+`File`. The executable that wraps Swift compiler invocations.
""",
"test_configuration": """\
`Struct` containing the following fields:
diff --git a/swift/toolchains/config/compile_config.bzl b/swift/toolchains/config/compile_config.bzl
index 588b36ae7..8d53ac964 100644
--- a/swift/toolchains/config/compile_config.bzl
+++ b/swift/toolchains/config/compile_config.bzl
@@ -20,6 +20,8 @@ load("@bazel_skylib//lib:types.bzl", "types")
load(
"//swift/internal:action_names.bzl",
"SWIFT_ACTION_COMPILE",
+ "SWIFT_ACTION_COMPILE_CODEGEN",
+ "SWIFT_ACTION_COMPILE_MODULE",
"SWIFT_ACTION_COMPILE_MODULE_INTERFACE",
"SWIFT_ACTION_DERIVE_FILES",
"SWIFT_ACTION_DUMP_AST",
@@ -70,6 +72,7 @@ load(
"SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD",
"SWIFT_FEATURE_NO_ASAN_VERSION_CHECK",
"SWIFT_FEATURE_OPT",
+ "SWIFT_FEATURE_OPT_USES_CMO",
"SWIFT_FEATURE_OPT_USES_OSIZE",
"SWIFT_FEATURE_OPT_USES_WMO",
"SWIFT_FEATURE_REWRITE_GENERATED_HEADER",
@@ -89,6 +92,10 @@ load(
"SWIFT_FEATURE__SUPPORTS_V6",
"SWIFT_FEATURE__WMO_IN_SWIFTCOPTS",
)
+load(
+ "//swift/internal:optimization.bzl",
+ "is_wmo_manually_requested",
+)
load(":action_config.bzl", "ActionConfigInfo", "ConfigResultInfo", "add_arg")
# The number of threads to use for WMO builds, using the same number of cores
@@ -97,14 +104,6 @@ load(":action_config.bzl", "ActionConfigInfo", "ConfigResultInfo", "add_arg")
# when an API to obtain this is available.
_DEFAULT_WMO_THREAD_COUNT = 12
-# Swift command line flags that enable whole module optimization. (This
-# dictionary is used as a set for quick lookup; the values are irrelevant.)
-_WMO_FLAGS = {
- "-wmo": True,
- "-whole-module-optimization": True,
- "-force-single-frontend-invocation": True,
-}
-
def compile_action_configs(
*,
additional_objc_copts = [],
@@ -140,23 +139,30 @@ def compile_action_configs(
action_configs = [
# Emit object file(s).
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-emit-object")],
not_features = [SWIFT_FEATURE_EMIT_BC],
),
# Emit llvm bc file(s).
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-emit-bc")],
features = [SWIFT_FEATURE_EMIT_BC],
),
# Add the single object file or object file map, whichever is needed.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [_output_object_or_file_map_configurator],
),
+ ActionConfigInfo(
+ actions = [
+ SWIFT_ACTION_COMPILE_CODEGEN,
+ SWIFT_ACTION_COMPILE_MODULE,
+ ],
+ configurators = [_compile_step_configurator],
+ ),
ActionConfigInfo(
actions = [SWIFT_ACTION_DERIVE_FILES],
configurators = [_output_swiftmodule_or_file_map_configurator],
@@ -177,7 +183,7 @@ def compile_action_configs(
# Don't embed Clang module breadcrumbs in debug info.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-Xfrontend", "-no-clang-module-breadcrumbs"),
],
@@ -203,7 +209,7 @@ def compile_action_configs(
# Configure the path to the emitted .swiftmodule file.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [_emit_module_path_configurator],
not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
),
@@ -214,8 +220,7 @@ def compile_action_configs(
# Configure library evolution and the path to the .swiftinterface file.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [add_arg("-enable-library-evolution")],
@@ -224,6 +229,7 @@ def compile_action_configs(
ActionConfigInfo(
actions = [
SWIFT_ACTION_COMPILE,
+ SWIFT_ACTION_COMPILE_MODULE,
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [_emit_module_interface_path_configurator],
@@ -232,6 +238,7 @@ def compile_action_configs(
ActionConfigInfo(
actions = [
SWIFT_ACTION_COMPILE,
+ SWIFT_ACTION_COMPILE_MODULE,
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [_emit_private_module_interface_path_configurator],
@@ -240,7 +247,10 @@ def compile_action_configs(
# Configure the path to the emitted *-Swift.h file.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = [
+ SWIFT_ACTION_COMPILE,
+ SWIFT_ACTION_COMPILE_MODULE,
+ ],
configurators = [_emit_objc_header_path_configurator],
not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
),
@@ -251,25 +261,25 @@ def compile_action_configs(
# Configure enforce exclusivity checks if enabled.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-enforce-exclusivity=checked")],
features = [SWIFT_FEATURE_CHECKED_EXCLUSIVITY],
),
# Configure constant value extraction.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [_constant_value_extraction_configurator],
),
# Link Time Optimization (LTO).
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-lto=llvm-thin")],
features = [SWIFT_FEATURE_THIN_LTO],
),
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-lto=llvm-full")],
features = [SWIFT_FEATURE_FULL_LTO],
),
@@ -294,7 +304,10 @@ def compile_action_configs(
action_configs.append(
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = [
+ SWIFT_ACTION_COMPILE,
+ SWIFT_ACTION_COMPILE_MODULE,
+ ],
configurators = [generated_header_rewriter_configurator],
features = [SWIFT_FEATURE_REWRITE_GENERATED_HEADER],
),
@@ -310,8 +323,7 @@ def compile_action_configs(
# Define appropriate conditional compilation symbols depending on the
# build mode.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -319,8 +331,7 @@ def compile_action_configs(
features = [[SWIFT_FEATURE_DBG], [SWIFT_FEATURE_FASTBUILD]],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -332,8 +343,7 @@ def compile_action_configs(
# `-O` unless the `swift.opt_uses_osize` feature is enabled, then use
# `-Osize`.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
],
@@ -341,8 +351,7 @@ def compile_action_configs(
features = [[SWIFT_FEATURE_DBG], [SWIFT_FEATURE_FASTBUILD]],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
],
@@ -351,20 +360,23 @@ def compile_action_configs(
not_features = [SWIFT_FEATURE_OPT_USES_OSIZE],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [add_arg("-Osize")],
features = [SWIFT_FEATURE_OPT, SWIFT_FEATURE_OPT_USES_OSIZE],
),
+ ActionConfigInfo(
+ actions = all_compile_action_names(),
+ configurators = [add_arg("-disable-cmo")],
+ not_features = [SWIFT_FEATURE_OPT_USES_CMO],
+ ),
# If the `swift.opt_uses_wmo` feature is enabled, opt builds should also
# automatically imply whole-module optimization.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [add_arg("-whole-module-optimization")],
@@ -376,7 +388,7 @@ def compile_action_configs(
# Improve dead-code stripping.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-Xfrontend", "-internalize-at-link")],
features = [SWIFT_FEATURE_INTERNALIZE_AT_LINK],
),
@@ -384,8 +396,7 @@ def compile_action_configs(
# Enable or disable serialization of debugging options into
# swiftmodules.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -394,8 +405,7 @@ def compile_action_configs(
features = [SWIFT_FEATURE_CACHEABLE_SWIFTMODULES],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -409,8 +419,7 @@ def compile_action_configs(
# Enable testability if requested.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -420,8 +429,7 @@ def compile_action_configs(
# Enable suppress-warnings if requested.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -433,8 +441,7 @@ def compile_action_configs(
# Enable warnings-as-errors if requested.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -446,8 +453,7 @@ def compile_action_configs(
# Disable Swift sandbox.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -459,8 +465,7 @@ def compile_action_configs(
# Set Developer Framework search paths
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -479,16 +484,14 @@ def compile_action_configs(
# `dsymutil` produces spurious warnings about symbols in the debug map
# when run on DI emitted by `-gline-tables-only`.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [add_arg("-g")],
features = [[SWIFT_FEATURE_DBG], [SWIFT_FEATURE_FULL_DEBUG_INFO]],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -510,8 +513,7 @@ def compile_action_configs(
features = [[SWIFT_FEATURE_DBG], [SWIFT_FEATURE_FULL_DEBUG_INFO]],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [add_arg("-gline-tables-only")],
@@ -524,8 +526,7 @@ def compile_action_configs(
# Make paths written into debug info workspace-relative.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
@@ -540,8 +541,7 @@ def compile_action_configs(
not_features = [SWIFT_FEATURE_FILE_PREFIX_MAP],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
@@ -553,8 +553,7 @@ def compile_action_configs(
# Make paths written into coverage info workspace-relative.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -567,9 +566,7 @@ def compile_action_configs(
# Ensure that .swiftsourceinfo files are tracked and not deleted by the worker
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [add_arg("-Xwrapped-swift=-emit-swiftsourceinfo")],
features = [SWIFT_FEATURE_DECLARE_SWIFTSOURCEINFO],
),
@@ -582,8 +579,7 @@ def compile_action_configs(
# supporting them either.
action_configs += [
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -593,16 +589,14 @@ def compile_action_configs(
features = [SWIFT_FEATURE_COVERAGE],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [add_arg("-sanitize=address")],
features = ["asan"],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -614,12 +608,12 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-sanitize=thread")],
features = ["tsan"],
),
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-sanitize=undefined"),
],
@@ -631,7 +625,7 @@ def compile_action_configs(
action_configs.append(
# Support for order-file instrumentation.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-sanitize=undefined"),
add_arg("-sanitize-coverage=func"),
@@ -652,7 +646,9 @@ def compile_action_configs(
# spelling, ensuring that the ClangImporter options section of the
# `.swiftmodule` file is hermetic.
ActionConfigInfo(
- actions = all_compile_action_names(),
+ actions = all_compile_action_names() + [
+ SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
+ ],
configurators = [
add_arg("-file-compilation-dir", "."),
],
@@ -661,8 +657,7 @@ def compile_action_configs(
# Treat paths in .modulemap files as workspace-relative, not modulemap-
# relative.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -680,8 +675,7 @@ def compile_action_configs(
# Configure how implicit modules are handled--either using the module
# cache, or disabled completely when using explicit modules.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -695,8 +689,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -710,8 +703,7 @@ def compile_action_configs(
not_features = [SWIFT_FEATURE_USE_C_MODULES],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -726,8 +718,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -739,8 +730,7 @@ def compile_action_configs(
# because all of them, including system dependencies, will be provided
# explicitly.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -753,8 +743,7 @@ def compile_action_configs(
),
# When using C modules, disable the implicit module cache.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -795,8 +784,7 @@ def compile_action_configs(
#### Search paths/explicit module map for Swift module dependencies
action_configs.extend([
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -824,8 +812,7 @@ def compile_action_configs(
features = [SWIFT_FEATURE_USE_EXPLICIT_SWIFT_MODULE_MAP],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -837,8 +824,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -859,19 +845,21 @@ def compile_action_configs(
features = [SWIFT_FEATURE_VFSOVERLAY],
),
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [_module_aliases_configurator],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [_plugins_configurator],
),
ActionConfigInfo(
actions = [
+ # TODO: b/351801556 - Verify that this is correct; it may need
+ # to be done by the codegen actions.
SWIFT_ACTION_COMPILE,
+ SWIFT_ACTION_COMPILE_MODULE,
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [_macro_expansion_configurator],
@@ -881,8 +869,7 @@ def compile_action_configs(
not_features = [SWIFT_FEATURE_OPT],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [_plugin_search_paths_configurator],
@@ -911,8 +898,7 @@ def compile_action_configs(
#### Search paths for framework dependencies
action_configs.extend([
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -943,8 +929,7 @@ def compile_action_configs(
action_configs.extend([
# Pass flags to Clang for search paths and propagated defines.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -961,8 +946,7 @@ def compile_action_configs(
# Pass flags to Clang for dependencies' module maps or explicit modules,
# whichever are being used for this build.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -973,8 +957,7 @@ def compile_action_configs(
features = [SWIFT_FEATURE_USE_C_MODULES],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -1005,8 +988,7 @@ def compile_action_configs(
# Request color diagnostics, since Bazel pipes the output and causes the
# driver's TTY check to fail.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
@@ -1028,6 +1010,9 @@ def compile_action_configs(
# performance hack.
ActionConfigInfo(
actions = [
+ # Only use for legacy Swift compile planning. Parallelized
+ # builds cannot use batch mode, because Bazel needs to control
+ # the batching directly.
SWIFT_ACTION_COMPILE,
SWIFT_ACTION_DERIVE_FILES,
],
@@ -1042,8 +1027,7 @@ def compile_action_configs(
# Set the number of threads to use for WMO. (We can skip this if we know
# we'll already be applying `-num-threads` via `--swiftcopt` flags.)
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -1060,8 +1044,7 @@ def compile_action_configs(
not_features = [SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -1079,8 +1062,7 @@ def compile_action_configs(
# Set the module name.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
@@ -1090,8 +1072,7 @@ def compile_action_configs(
configurators = [_module_name_configurator],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
@@ -1103,8 +1084,7 @@ def compile_action_configs(
# Set the package name.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
@@ -1123,12 +1103,12 @@ def compile_action_configs(
# Configure index-while-building.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [_index_while_building_configurator],
features = [SWIFT_FEATURE_INDEX_WHILE_BUILDING],
),
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-index-include-locals")],
features = [
SWIFT_FEATURE_INDEX_WHILE_BUILDING,
@@ -1136,7 +1116,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [add_arg("-index-ignore-system-modules")],
features = [
SWIFT_FEATURE_INDEX_WHILE_BUILDING,
@@ -1144,7 +1124,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-index-ignore-clang-modules"),
],
@@ -1171,7 +1151,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [_global_index_store_configurator],
features = [
SWIFT_FEATURE_INDEX_WHILE_BUILDING,
@@ -1181,23 +1161,21 @@ def compile_action_configs(
# Disable auto-linking for prebuilt static frameworks.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [_frameworks_disable_autolink_configurator],
),
# User-defined conditional compilation flags (defined for Swift; those
# passed directly to ClangImporter are handled above).
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
configurators = [_conditional_compilation_flag_configurator],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
],
@@ -1205,36 +1183,28 @@ def compile_action_configs(
features = [SWIFT_FEATURE_ENABLE_BARE_SLASH_REGEX],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [add_arg("-Xfrontend", "-disable-clang-spi")],
features = [
SWIFT_FEATURE_DISABLE_CLANG_SPI,
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [add_arg("-Xfrontend", "-disable-availability-checking")],
features = [
SWIFT_FEATURE_DISABLE_AVAILABILITY_CHECKING,
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [_upcoming_and_experimental_features_configurator],
features = [
SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES,
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [add_arg("-swift-version", "6")],
features = [
SWIFT_FEATURE_ENABLE_V6,
@@ -1251,8 +1221,7 @@ def compile_action_configs(
# `copts` attribute.
action_configs.append(
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -1263,8 +1232,7 @@ def compile_action_configs(
if additional_objc_copts:
action_configs.append(
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -1286,8 +1254,7 @@ def compile_action_configs(
# TODO(allevato): Determine if there are any uses of
# `-Xcc`-prefixed flags that need to be added to explicit module
# actions, or if we should advise against/forbid that.
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -1303,8 +1270,7 @@ def compile_action_configs(
action_configs.append(
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -1317,8 +1283,7 @@ def compile_action_configs(
# Add additional input files to the sandbox (does not modify flags).
action_configs.append(
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
],
@@ -1416,6 +1381,14 @@ def _output_ast_path_or_file_map_configurator(prerequisites, args):
args = args,
)
+def _compile_step_configurator(prerequisites, args):
+ """Adds the parallelized compilation plan step to the command line."""
+ step = prerequisites.compile_step
+ args.add("-Xwrapped-swift=-compile-step={}={}".format(
+ step.action,
+ step.output,
+ ))
+
def _output_pcm_file_configurator(prerequisites, args):
"""Adds the `.pcm` output path to the command line."""
args.add("-o", prerequisites.pcm_file)
@@ -1523,7 +1496,7 @@ def _pcm_developer_framework_paths_configurator(prerequisites, args):
def _batch_mode_configurator(prerequisites, args):
"""Adds flags to enable batch compilation mode."""
- if not _is_wmo_manually_requested(prerequisites.user_compile_flags):
+ if not is_wmo_manually_requested(prerequisites.user_compile_flags):
args.add("-enable-batch-mode")
def _c_layering_check_configurator(prerequisites, args):
@@ -2111,25 +2084,11 @@ def _make_wmo_thread_count_configurator(should_check_flags):
return lambda _prerequisites, args: _add_num_threads(args)
def _flag_checking_wmo_thread_count_configurator(prerequisites, args):
- if _is_wmo_manually_requested(prerequisites.user_compile_flags):
+ if is_wmo_manually_requested(prerequisites.user_compile_flags):
_add_num_threads(args)
return _flag_checking_wmo_thread_count_configurator
-def _is_wmo_manually_requested(user_compile_flags):
- """Returns `True` if a WMO flag is in the given list of compiler flags.
-
- Args:
- user_compile_flags: A list of compiler flags to scan for WMO usage.
-
- Returns:
- True if WMO is enabled in the given list of flags.
- """
- for copt in user_compile_flags:
- if copt in _WMO_FLAGS:
- return True
- return False
-
def _exclude_swift_incompatible_define(define):
"""A `map_each` helper that excludes a define if it is not Swift-compatible.
diff --git a/swift/toolchains/swift_toolchain.bzl b/swift/toolchains/swift_toolchain.bzl
index e879ce7bf..85cf1c740 100644
--- a/swift/toolchains/swift_toolchain.bzl
+++ b/swift/toolchains/swift_toolchain.bzl
@@ -60,6 +60,7 @@ load(
"default_features_for_toolchain",
"features_for_build_modes",
)
+load("//swift/internal:optimization.bzl", "optimization_features_from_swiftcopts")
load(
"//swift/internal:providers.bzl",
"SwiftCrossImportOverlayInfo",
@@ -71,7 +72,6 @@ load(
"collect_implicit_deps_providers",
"get_swift_executable_for_toolchain",
)
-load("//swift/internal:wmo.bzl", "features_from_swiftcopts")
load(
"//swift/toolchains/config:action_config.bzl",
"ActionConfigInfo",
@@ -139,7 +139,7 @@ def _all_tool_configs(
driver_config = _driver_config(mode = "swiftc"),
resource_set = _swift_compile_resource_set,
use_param_file = True,
- worker_mode = "persistent",
+ worker_mode = "wrap",
env = env,
)
@@ -453,9 +453,9 @@ def _swift_toolchain_impl(ctx):
# Combine build mode features, autoconfigured features, and required
# features.
+ features_from_swiftcopts, _ = optimization_features_from_swiftcopts(swiftcopts = swiftcopts)
requested_features = (
- features_for_build_modes(ctx) +
- features_from_swiftcopts(swiftcopts = swiftcopts)
+ features_for_build_modes(ctx) + features_from_swiftcopts
)
requested_features.extend(default_features_for_toolchain(
target_triple = target_triple,
@@ -662,8 +662,7 @@ to the compiler for exec transition builds.
allow_files = True,
default = Label("//tools/worker"),
doc = """\
-An executable that wraps Swift compiler invocations and also provides support
-for incremental compilation using a persistent mode.
+An executable that wraps Swift compiler invocations.
""",
executable = True,
),
diff --git a/swift/toolchains/xcode_swift_toolchain.bzl b/swift/toolchains/xcode_swift_toolchain.bzl
index a7cdb456b..f9d7a9734 100644
--- a/swift/toolchains/xcode_swift_toolchain.bzl
+++ b/swift/toolchains/xcode_swift_toolchain.bzl
@@ -40,12 +40,15 @@ load(
load(
"//swift/internal:action_names.bzl",
"SWIFT_ACTION_COMPILE",
+ "SWIFT_ACTION_COMPILE_CODEGEN",
+ "SWIFT_ACTION_COMPILE_MODULE",
"SWIFT_ACTION_COMPILE_MODULE_INTERFACE",
"SWIFT_ACTION_DERIVE_FILES",
"SWIFT_ACTION_DUMP_AST",
"SWIFT_ACTION_PRECOMPILE_C_MODULE",
"SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT",
"SWIFT_ACTION_SYNTHESIZE_INTERFACE",
+ "all_compile_action_names",
)
load("//swift/internal:attrs.bzl", "swift_toolchain_driver_attrs")
load("//swift/internal:developer_dirs.bzl", "swift_developer_lib_dir")
@@ -66,6 +69,10 @@ load(
"default_features_for_toolchain",
"features_for_build_modes",
)
+load(
+ "//swift/internal:optimization.bzl",
+ "optimization_features_from_swiftcopts",
+)
load(
"//swift/internal:providers.bzl",
"SwiftCrossImportOverlayInfo",
@@ -78,7 +85,6 @@ load(
"compact",
"get_swift_executable_for_toolchain",
)
-load("//swift/internal:wmo.bzl", "wmo_features_from_swiftcopts")
load(
"//swift/toolchains/config:action_config.bzl",
"ActionConfigInfo",
@@ -327,8 +333,7 @@ def _all_action_configs(
# Basic compilation flags (target triple and toolchain search paths).
action_configs = [
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
@@ -346,8 +351,7 @@ def _all_action_configs(
action_configs.extend([
# Xcode path remapping
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -361,8 +365,7 @@ def _all_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
SWIFT_ACTION_DERIVE_FILES,
],
@@ -381,8 +384,7 @@ def _all_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
@@ -406,8 +408,7 @@ def _all_action_configs(
# directory so that modules are found correctly.
action_configs.append(
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
@@ -504,11 +505,13 @@ def _all_tool_configs(
execution_requirements = execution_requirements,
resource_set = _swift_compile_resource_set,
use_param_file = True,
- worker_mode = "persistent",
+ worker_mode = "wrap",
)
tool_configs = {
SWIFT_ACTION_COMPILE: tool_config,
+ SWIFT_ACTION_COMPILE_CODEGEN: tool_config,
+ SWIFT_ACTION_COMPILE_MODULE: tool_config,
SWIFT_ACTION_DERIVE_FILES: tool_config,
SWIFT_ACTION_DUMP_AST: tool_config,
SWIFT_ACTION_PRECOMPILE_C_MODULE: (
@@ -683,10 +686,16 @@ def _xcode_swift_toolchain_impl(ctx):
# Compute the default requested features and conditional ones based on Xcode
# version.
- requested_features = features_for_build_modes(
- ctx,
- cpp_fragment = cpp_fragment,
- ) + wmo_features_from_swiftcopts(swiftcopts = swiftcopts)
+ requested_features, unsupported_features = (
+ optimization_features_from_swiftcopts(swiftcopts = swiftcopts)
+ )
+ build_mode_requested_features, build_mode_unsupported_features = (
+ features_for_build_modes(
+ ctx,
+ cpp_fragment = cpp_fragment,
+ )
+ )
+ requested_features.extend(build_mode_requested_features)
requested_features.extend(ctx.features)
requested_features.extend(ctx.attr.default_enabled_features)
requested_features.extend(default_features_for_toolchain(
@@ -711,9 +720,12 @@ def _xcode_swift_toolchain_impl(ctx):
requested_features.append(SWIFT_FEATURE__SUPPORTS_V6)
unsupported_features = ctx.disabled_features + [
+ # `-fmodule-map-file-home-is-cwd` is incompatible with Apple's module maps,
+ # which we must use for system frameworks.
SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD,
]
unsupported_features.extend(ctx.attr.default_unsupported_features)
+ unsupported_features.extend(build_mode_unsupported_features)
env = _xcode_env(target_triple = target_triple, xcode_config = xcode_config)
@@ -779,6 +791,7 @@ def _xcode_swift_toolchain_impl(ctx):
clang_implicit_deps_providers = collect_implicit_deps_providers(
ctx.attr.clang_implicit_deps,
),
+ codegen_batch_size = 8,
cross_import_overlays = [
target[SwiftCrossImportOverlayInfo]
for target in ctx.attr.cross_import_overlays
@@ -972,8 +985,7 @@ to the compiler for exec transition builds.
allow_files = True,
default = Label("//tools/worker:worker_wrapper"),
doc = """\
-An executable that wraps Swift compiler invocations and also provides support
-for incremental compilation using a persistent mode.
+An executable that wraps Swift compiler invocations.
""",
executable = True,
),
diff --git a/test/BUILD b/test/BUILD
index 35deeeb31..6155ff6a0 100644
--- a/test/BUILD
+++ b/test/BUILD
@@ -16,6 +16,7 @@ load(":module_cache_settings_tests.bzl", "module_cache_settings_test_suite")
load(":module_interface_tests.bzl", "module_interface_test_suite")
load(":module_mapping_tests.bzl", "module_mapping_test_suite")
load(":output_file_map_tests.bzl", "output_file_map_test_suite")
+load(":parallel_compilation_tests.bzl", "parallel_compilation_test_suite")
load(":pch_output_dir_tests.bzl", "pch_output_dir_test_suite")
load(":private_deps_tests.bzl", "private_deps_test_suite")
load(":private_swiftinterface_tests.bzl", "private_swiftinterface_test_suite")
@@ -80,6 +81,10 @@ synthesize_interface_test_suite(
],
)
+parallel_compilation_test_suite(
+ name = "parallel_compilation",
+)
+
pch_output_dir_test_suite(name = "pch_output_dir_settings")
private_swiftinterface_test_suite(name = "private_swiftinterface")
diff --git a/test/coverage_settings_tests.bzl b/test/coverage_settings_tests.bzl
index 4788109b6..06b755ac7 100644
--- a/test/coverage_settings_tests.bzl
+++ b/test/coverage_settings_tests.bzl
@@ -46,7 +46,7 @@ def coverage_settings_test_suite(name, tags = []):
"-profile-coverage-mapping",
"-Xwrapped-swift=-coverage-prefix-pwd-is-dot",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -60,7 +60,7 @@ def coverage_settings_test_suite(name, tags = []):
not_expected_argv = [
"-Xwrapped-swift=-coverage-prefix-pwd-is-dot",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -72,6 +72,6 @@ def coverage_settings_test_suite(name, tags = []):
"__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR",
],
target_compatible_with = ["@platforms//os:macos"],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_under_test = "//test/fixtures/debug_settings:simple",
)
diff --git a/test/debug_settings_tests.bzl b/test/debug_settings_tests.bzl
index 15db65d1e..35566bc22 100644
--- a/test/debug_settings_tests.bzl
+++ b/test/debug_settings_tests.bzl
@@ -144,7 +144,7 @@ def debug_settings_test_suite(name, tags = []):
"-Xfrontend -no-serialize-debugging-options",
"-gline-tables-only",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -158,7 +158,7 @@ def debug_settings_test_suite(name, tags = []):
not_expected_argv = [
"-Xwrapped-swift=-debug-prefix-pwd-is-dot",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -179,7 +179,7 @@ def debug_settings_test_suite(name, tags = []):
"-Xfrontend -serialize-debugging-options",
"-gline-tables-only",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -199,7 +199,7 @@ def debug_settings_test_suite(name, tags = []):
"-Xfrontend -no-serialize-debugging-options",
"-g",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -219,7 +219,7 @@ def debug_settings_test_suite(name, tags = []):
"-Xfrontend -no-serialize-debugging-options",
"-gline-tables-only",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -254,6 +254,8 @@ def debug_settings_test_suite(name, tags = []):
not_expected_argv = [
"-Xfrontend -serialize-debugging-options",
],
+ # In optimized mode, the driver still uses a single invocation for both
+ # the module and for codegen.
mnemonic = "SwiftCompile",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
@@ -266,7 +268,7 @@ def debug_settings_test_suite(name, tags = []):
"__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR",
],
target_compatible_with = ["@platforms//os:macos"],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
diff --git a/test/features_tests.bzl b/test/features_tests.bzl
index d31d97b93..648516f75 100644
--- a/test/features_tests.bzl
+++ b/test/features_tests.bzl
@@ -149,7 +149,7 @@ def features_test_suite(name, tags = []):
not_expected_argv = [
"-Xwrapped-swift=-file-prefix-pwd-is-dot",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -162,7 +162,7 @@ def features_test_suite(name, tags = []):
"__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR",
],
target_compatible_with = ["@platforms//os:macos"],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -172,7 +172,7 @@ def features_test_suite(name, tags = []):
not_expected_argv = [
"-Xwrapped-swift=-global-index-store-import-path=",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -182,7 +182,7 @@ def features_test_suite(name, tags = []):
expected_argv = [
"-Xwrapped-swift=-global-index-store-import-path=bazel-out/_global_index_store",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_compatible_with = ["@platforms//os:macos"],
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -193,7 +193,7 @@ def features_test_suite(name, tags = []):
expected_argv = [
"-disable-sandbox",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_compatible_with = ["@platforms//os:macos"],
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -202,6 +202,8 @@ def features_test_suite(name, tags = []):
name = "{}_default_opt_test".format(name),
tags = all_tags,
expected_argv = ["-emit-object", "-O", "-whole-module-optimization"],
+ # In optimized mode, the driver still uses a single invocation for both
+ # the module and for codegen.
mnemonic = "SwiftCompile",
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -211,7 +213,7 @@ def features_test_suite(name, tags = []):
tags = all_tags,
expected_argv = ["-emit-object", "-O"],
not_expected_argv = ["-whole-module-optimization"],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
target_under_test = "//test/fixtures/debug_settings:simple",
)
diff --git a/test/fixtures/debug_settings/BUILD b/test/fixtures/debug_settings/BUILD
index d42aee8e8..35a9707b2 100644
--- a/test/fixtures/debug_settings/BUILD
+++ b/test/fixtures/debug_settings/BUILD
@@ -16,5 +16,18 @@ licenses(["notice"])
swift_library(
name = "simple",
srcs = ["Empty.swift"],
+ features = [
+ # TODO: b/351801556 - Remove this when it is the default on all
+ # toolchains.
+ "swift.compile_in_parallel",
+ ],
+ tags = FIXTURE_TAGS,
+)
+
+# TODO: The `default_no_split_args` split_derived_files_generation is not supported in parallel.
+# We need to handle falling back to non-parallel compilation when this feature is enabled, but dont currently.
+swift_library(
+ name = "simple_batch_mode",
+ srcs = ["Empty.swift"],
tags = FIXTURE_TAGS,
)
diff --git a/test/fixtures/parallel_compilation/BUILD b/test/fixtures/parallel_compilation/BUILD
new file mode 100644
index 000000000..153015c33
--- /dev/null
+++ b/test/fixtures/parallel_compilation/BUILD
@@ -0,0 +1,76 @@
+load(
+ "//swift:swift_library.bzl",
+ "swift_library",
+)
+load("//test/fixtures:common.bzl", "FIXTURE_TAGS")
+
+package(
+ default_visibility = ["//test:__subpackages__"],
+ features = ["swift.compile_in_parallel"],
+)
+
+licenses(["notice"])
+
+###############################################################################
+
+swift_library(
+ name = "no_opt_no_wmo",
+ srcs = ["Empty.swift"],
+ tags = FIXTURE_TAGS,
+)
+
+swift_library(
+ name = "no_opt_with_wmo",
+ srcs = ["Empty.swift"],
+ copts = ["-wmo"],
+ tags = FIXTURE_TAGS,
+)
+
+swift_library(
+ name = "with_opt_no_wmo",
+ srcs = ["Empty.swift"],
+ copts = ["-O"],
+ tags = FIXTURE_TAGS,
+)
+
+swift_library(
+ name = "with_opt_with_wmo_no_cmo",
+ srcs = ["Empty.swift"],
+ copts = [
+ "-O",
+ "-wmo",
+ ],
+ features = ["-swift.opt_uses_cmo"],
+ tags = FIXTURE_TAGS,
+)
+
+swift_library(
+ name = "with_opt_with_wmo_with_cmo",
+ srcs = ["Empty.swift"],
+ copts = [
+ "-O",
+ "-wmo",
+ ],
+ tags = FIXTURE_TAGS,
+)
+
+swift_library(
+ name = "with_opt_with_wmo_with_library_evolution",
+ srcs = ["Empty.swift"],
+ copts = [
+ "-O",
+ "-wmo",
+ ],
+ library_evolution = True,
+ tags = FIXTURE_TAGS,
+)
+
+swift_library(
+ name = "onone_with_wmo",
+ srcs = ["Empty.swift"],
+ copts = [
+ "-Onone",
+ "-wmo",
+ ],
+ tags = FIXTURE_TAGS,
+)
diff --git a/test/fixtures/parallel_compilation/Empty.swift b/test/fixtures/parallel_compilation/Empty.swift
new file mode 100644
index 000000000..bd9ec079d
--- /dev/null
+++ b/test/fixtures/parallel_compilation/Empty.swift
@@ -0,0 +1 @@
+// Intentionally empty.
diff --git a/test/module_cache_settings_tests.bzl b/test/module_cache_settings_tests.bzl
index 8b41e7ce4..6b66050c4 100644
--- a/test/module_cache_settings_tests.bzl
+++ b/test/module_cache_settings_tests.bzl
@@ -67,7 +67,7 @@ def module_cache_settings_test_suite(name, tags = []):
"-Xwrapped-swift=-ephemeral-module-cache",
"/tmp/__build_bazel_rules_swift/swift_module_cache/$(WORKSPACE_NAME)",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -83,7 +83,7 @@ def module_cache_settings_test_suite(name, tags = []):
not_expected_argv = [
"-Xwrapped-swift=-ephemeral-module-cache",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -95,7 +95,7 @@ def module_cache_settings_test_suite(name, tags = []):
not_expected_argv = [
"/tmp/__build_bazel_rules_swift/swift_module_cache/$(WORKSPACE_NAME)",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
diff --git a/test/parallel_compilation_tests.bzl b/test/parallel_compilation_tests.bzl
new file mode 100644
index 000000000..afe6ebfa2
--- /dev/null
+++ b/test/parallel_compilation_tests.bzl
@@ -0,0 +1,160 @@
+# Copyright 2024 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Tests for parallel compilation."""
+
+load("@bazel_skylib//rules:build_test.bzl", "build_test")
+load(
+ "//test/rules:actions_created_test.bzl",
+ "actions_created_test",
+ "make_actions_created_test_rule",
+)
+
+visibility("private")
+
+opt_actions_create_test = make_actions_created_test_rule(
+ config_settings = {
+ "//command_line_option:compilation_mode": "opt",
+ },
+)
+
+opt_via_swiftcopt_actions_create_test = make_actions_created_test_rule(
+ config_settings = {
+ str(Label("//swift:copt")): ["-O"],
+ },
+)
+
+opt_with_wmo_via_swiftcopt_actions_create_test = make_actions_created_test_rule(
+ config_settings = {
+ "//command_line_option:compilation_mode": "opt",
+ str(Label("//swift:copt")): [
+ "-whole-module-optimization",
+ ],
+ },
+)
+
+def parallel_compilation_test_suite(name, tags = []):
+ """Test suite for parallel compilation.
+
+ Args:
+ name: The base name to be used in targets created by this macro.
+ tags: Additional tags to apply to each test.
+ """
+ all_tags = [name] + tags
+
+ # Non-optimized, non-WMO can be compiled in parallel.
+ actions_created_test(
+ name = "{}_no_opt_no_wmo".format(name),
+ mnemonics = ["SwiftCompileModule", "SwiftCompileCodegen", "-SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:no_opt_no_wmo",
+ )
+
+ # Non-optimized, with-WMO can be compiled in parallel.
+ actions_created_test(
+ name = "{}_no_opt_with_wmo".format(name),
+ mnemonics = ["SwiftCompileModule", "SwiftCompileCodegen", "-SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:no_opt_with_wmo",
+ )
+
+ # Optimized, non-WMO can be compiled in parallel.
+ actions_created_test(
+ name = "{}_with_opt_no_wmo".format(name),
+ mnemonics = ["SwiftCompileModule", "SwiftCompileCodegen", "-SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:with_opt_no_wmo",
+ )
+
+ # Optimized, with-WMO can be compiled in parallel if CMO is also disabled.
+ actions_created_test(
+ name = "{}_with_opt_with_wmo_no_cmo".format(name),
+ mnemonics = ["SwiftCompileModule", "SwiftCompileCodegen", "-SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:with_opt_with_wmo_no_cmo",
+ )
+
+ # Optimized, with-WMO cannot be compiled in parallel if CMO is enabled.
+ actions_created_test(
+ name = "{}_with_opt_with_wmo_with_cmo".format(name),
+ mnemonics = ["-SwiftCompileModule", "-SwiftCompileCodegen", "SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:with_opt_with_wmo_with_cmo",
+ )
+
+ # Force `-c opt` on a non-optimized, with-WMO target and make sure we don't
+ # plan parallel compilation there.
+ opt_actions_create_test(
+ name = "{}_no_opt_with_wmo_but_compilation_mode_opt".format(name),
+ mnemonics = ["-SwiftCompileModule", "-SwiftCompileCodegen", "SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:no_opt_with_wmo",
+ )
+
+ # Force `-O` using the `copt` flag on a non-optimized, with-WMO target and
+ # make sure we don't plan parallel compilation there.
+ opt_via_swiftcopt_actions_create_test(
+ name = "{}_no_opt_with_wmo_but_swiftcopt_dash_O".format(name),
+ mnemonics = ["-SwiftCompileModule", "-SwiftCompileCodegen", "SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:no_opt_with_wmo",
+ )
+
+ # Optimized, with-WMO can be compiled in parallel if library evolution is
+ # enabled (which implicitly disables CMO).
+ actions_created_test(
+ name = "{}_with_opt_with_wmo_with_library_evolution".format(name),
+ mnemonics = ["SwiftCompileModule", "SwiftCompileCodegen", "-SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:with_opt_with_wmo_with_library_evolution",
+ )
+
+ # Make sure that when we look for optimizer flags, we don't treat `-Onone`
+ # as being optimized.
+ actions_created_test(
+ name = "{}_onone_with_wmo".format(name),
+ mnemonics = ["SwiftCompileModule", "SwiftCompileCodegen", "-SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:onone_with_wmo",
+ )
+
+ # Optimized (via `-c opt`) with-WMO cannot be compiled in parallel if CMO is
+ # enabled (the default).
+ opt_with_wmo_via_swiftcopt_actions_create_test(
+ name = "{}_with_opt_via_compilation_mode_opt_with_wmo".format(name),
+ mnemonics = ["-SwiftCompileModule", "-SwiftCompileCodegen", "SwiftCompile"],
+ tags = all_tags,
+ target_under_test = "//test/fixtures/parallel_compilation:no_opt_no_wmo",
+ )
+
+ # The analysis tests verify that we register the actions we expect. Use a
+ # `build_test` to make sure the actions execute successfully.
+ build_test(
+ name = "{}_build_test".format(name),
+ targets = [
+ "//test/fixtures/parallel_compilation:no_opt_no_wmo",
+ "//test/fixtures/parallel_compilation:no_opt_with_wmo",
+ "//test/fixtures/parallel_compilation:with_opt_no_wmo",
+ "//test/fixtures/parallel_compilation:with_opt_with_wmo_no_cmo",
+ "//test/fixtures/parallel_compilation:with_opt_with_wmo_with_cmo",
+ "//test/fixtures/parallel_compilation:with_opt_with_wmo_with_library_evolution",
+ "//test/fixtures/parallel_compilation:onone_with_wmo",
+ ],
+ tags = all_tags,
+ )
+
+ native.test_suite(
+ name = name,
+ tags = all_tags,
+ )
diff --git a/test/pch_output_dir_tests.bzl b/test/pch_output_dir_tests.bzl
index 3b2db318c..294ec5175 100644
--- a/test/pch_output_dir_tests.bzl
+++ b/test/pch_output_dir_tests.bzl
@@ -45,7 +45,7 @@ def pch_output_dir_test_suite(name, tags = []):
# can't verify the whole argument here. It has the configuration
# fragment baked in.
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
diff --git a/test/rules/actions_created_test.bzl b/test/rules/actions_created_test.bzl
new file mode 100644
index 000000000..3fa5768ba
--- /dev/null
+++ b/test/rules/actions_created_test.bzl
@@ -0,0 +1,93 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Rules for testing whether or not actions are simply created by a rule."""
+
+load("@bazel_skylib//lib:collections.bzl", "collections")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "unittest")
+
+visibility([
+ "//test/...",
+])
+
+def _actions_created_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ target_under_test = analysistest.target_under_test(env)
+
+ actions = analysistest.target_actions(env)
+ for mnemonic in ctx.attr.mnemonics:
+ is_negative_test = mnemonic.startswith("-")
+ if is_negative_test:
+ mnemonic = mnemonic[1:]
+
+ matching_actions = [
+ action
+ for action in actions
+ if action.mnemonic == mnemonic
+ ]
+ actual_mnemonics = collections.uniq(
+ [action.mnemonic for action in actions],
+ )
+
+ if is_negative_test and matching_actions:
+ unittest.fail(
+ env,
+ ("Target '{}' registered actions with the mnemonic '{}', " +
+ "but it was not expected to (it had {}).").format(
+ str(target_under_test.label),
+ mnemonic,
+ actual_mnemonics,
+ ),
+ )
+ elif not is_negative_test and not matching_actions:
+ unittest.fail(
+ env,
+ ("Target '{}' registered no actions with the expected " +
+ "mnemonic '{}' (it had {}).").format(
+ str(target_under_test.label),
+ mnemonic,
+ actual_mnemonics,
+ ),
+ )
+
+ return analysistest.end(env)
+
+def make_actions_created_test_rule(config_settings = {}):
+ """Returns a new `actions_created_test`-like rule with custom configs.
+
+ Args:
+ config_settings: A dictionary of configuration settings and their values
+ that should be applied during tests.
+
+ Returns:
+ A rule returned by `analysistest.make` that has the
+ `actions_created_test` interface and the given config settings.
+ """
+ return analysistest.make(
+ _actions_created_test_impl,
+ attrs = {
+ "mnemonics": attr.string_list(
+ mandatory = True,
+ doc = """\
+A list of mnemonics that are expected to be created by the target under test.
+A mnemonic may also be preceded by a `-` to indicate that it is not expected
+to be created and the test should fail if it finds one.
+""",
+ ),
+ },
+ config_settings = config_settings,
+ )
+
+# A default instantiation of the rule when no custom config settings are needed.
+actions_created_test = make_actions_created_test_rule()
diff --git a/test/split_derived_files_tests.bzl b/test/split_derived_files_tests.bzl
index b53c7cbd6..14e771569 100644
--- a/test/split_derived_files_tests.bzl
+++ b/test/split_derived_files_tests.bzl
@@ -138,14 +138,14 @@ def split_derived_files_test_suite(name, tags = []):
"-emit-module-path",
"-emit-object",
"-enable-batch-mode",
- "simple.output_file_map.json",
+ "simple_batch_mode.output_file_map.json",
],
not_expected_argv = [
- "simple.derived_output_file_map.json",
+ "simple_batch_mode.derived_output_file_map.json",
],
mnemonic = "SwiftCompile",
tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
+ target_under_test = "//test/fixtures/debug_settings:simple_batch_mode",
)
default_no_split_provider_test(
diff --git a/tools/common/BUILD b/tools/common/BUILD
index bdd8dcf69..35ba99b61 100644
--- a/tools/common/BUILD
+++ b/tools/common/BUILD
@@ -39,6 +39,11 @@ cc_library(
"-std=c++17",
],
}),
+ deps = [
+ ":temp_file",
+ "@abseil-cpp//absl/container:flat_hash_map",
+ "@abseil-cpp//absl/status:statusor",
+ ],
)
cc_library(
@@ -52,6 +57,94 @@ cc_library(
"-std=c++17",
],
}),
+ deps = [
+ "@abseil-cpp//absl/strings",
+ ],
+)
+
+cc_library(
+ name = "color",
+ hdrs = ["color.h"],
+ copts = selects.with_or({
+ ("//tools:clang-cl", "//tools:msvc"): [
+ "/std:c++17",
+ ],
+ "//conditions:default": [
+ "-std=c++17",
+ ],
+ }),
+)
+
+cc_library(
+ name = "file_system",
+ srcs = ["file_system.cc"],
+ hdrs = ["file_system.h"],
+ copts = selects.with_or({
+ ("//tools:clang-cl", "//tools:msvc"): [
+ "/std:c++17",
+ ],
+ "//conditions:default": [
+ "-std=c++17",
+ ],
+ }),
+ deps = [
+ ":path_utils",
+ ":status",
+ "@abseil-cpp//absl/cleanup",
+ "@abseil-cpp//absl/status:statusor",
+ "@abseil-cpp//absl/strings",
+ ],
+)
+
+cc_library(
+ name = "path_utils",
+ srcs = ["path_utils.cc"],
+ hdrs = ["path_utils.h"],
+ copts = selects.with_or({
+ ("//tools:clang-cl", "//tools:msvc"): [
+ "/std:c++17",
+ ],
+ "//conditions:default": [
+ "-std=c++17",
+ ],
+ }),
+ deps = [
+ "@abseil-cpp//absl/strings",
+ ],
+)
+
+cc_library(
+ name = "status",
+ srcs = ["status.cc"],
+ hdrs = ["status.h"],
+ copts = selects.with_or({
+ ("//tools:clang-cl", "//tools:msvc"): [
+ "/std:c++17",
+ ],
+ "//conditions:default": [
+ "-std=c++17",
+ ],
+ }),
+ deps = [
+ "@abseil-cpp//absl/status",
+ "@abseil-cpp//absl/strings",
+ ],
+)
+
+cc_library(
+ name = "target_triple",
+ hdrs = ["target_triple.h"],
+ copts = selects.with_or({
+ ("//tools:clang-cl", "//tools:msvc"): [
+ "/std:c++17",
+ ],
+ "//conditions:default": [
+ "-std=c++17",
+ ],
+ }),
+ deps = [
+ "@abseil-cpp//absl/strings",
+ ],
)
# Consumed by Bazel integration tests.
diff --git a/tools/common/bazel_substitutions.cc b/tools/common/bazel_substitutions.cc
index cf71de995..a85023607 100644
--- a/tools/common/bazel_substitutions.cc
+++ b/tools/common/bazel_substitutions.cc
@@ -15,133 +15,53 @@
#include "tools/common/bazel_substitutions.h"
#include
-#include
#include
-#include