diff --git a/MODULE.bazel b/MODULE.bazel
index 5ae3ab058..26b275259 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -14,8 +14,10 @@ bazel_dep(name = "apple_support", version = "1.24.2", repo_name = "build_bazel_a
bazel_dep(name = "rules_cc", version = "0.2.14")
bazel_dep(name = "rules_shell", version = "0.3.0")
bazel_dep(name = "platforms", version = "0.0.11")
-bazel_dep(name = "protobuf", version = "29.0", repo_name = "com_google_protobuf")
+bazel_dep(name = "protobuf", version = "30.0", repo_name = "com_google_protobuf")
bazel_dep(name = "nlohmann_json", version = "3.12.0.bcr.1", repo_name = "com_github_nlohmann_json")
+bazel_dep(name = "abseil-cpp", version = "20250127.0")
+bazel_dep(name = "re2", version = "2025-11-05")
bazel_dep(
name = "swift_argument_parser",
version = "1.3.1.2",
diff --git a/doc/providers.md b/doc/providers.md
index cc8e6f712..28ef7491f 100644
--- a/doc/providers.md
+++ b/doc/providers.md
@@ -110,11 +110,12 @@ Propagates Swift-specific information about a `proto_library`.
SwiftToolchainInfo(action_configs, cc_language, cc_toolchain_info, clang_implicit_deps_providers,
- const_protocols_to_gather, cross_import_overlays, debug_outputs_provider,
- developer_dirs, entry_point_linkopts_provider, feature_allowlists,
- generated_header_module_implicit_deps_providers, implicit_deps_providers,
- module_aliases, package_configurations, requested_features, root_dir, swift_worker,
- test_configuration, tool_configs, unsupported_features)
+ codegen_batch_size, const_protocols_to_gather, cross_import_overlays,
+ debug_outputs_provider, developer_dirs, entry_point_linkopts_provider,
+ feature_allowlists, generated_header_module_implicit_deps_providers,
+ implicit_deps_providers, module_aliases, package_configurations,
+ requested_features, root_dir, swift_worker, test_configuration, tool_configs,
+ unsupported_features)
Propagates information about a Swift toolchain to compilation and linking rules
@@ -128,6 +129,7 @@ that use the toolchain.
| cc_language | The `language` that should be passed to `cc_common` APIs that take it as an argument. |
| cc_toolchain_info | The `cc_common.CcToolchainInfo` provider from the Bazel C++ toolchain that this Swift toolchain depends on. |
| clang_implicit_deps_providers | A `struct` with the following fields, which represent providers from targets that should be added as implicit dependencies of any precompiled explicit C/Objective-C modules:
* `cc_infos`: A list of `CcInfo` providers from targets specified as the toolchain's implicit dependencies.
* `swift_infos`: A list of `SwiftInfo` providers from targets specified as the toolchain's implicit dependencies.
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 conformances' const values. |
| cross_import_overlays | A list of `SwiftCrossImportOverlayInfo` providers whose `SwiftInfo` providers will be automatically injected into the dependencies of Swift compilations if their declaring module and bystanding module are both already declared as dependencies. |
| debug_outputs_provider | An optional function that provides toolchain-specific logic around the handling of additional debug outputs for `swift_binary` and `swift_test` targets.
If specified, this function must take the following keyword arguments:
* `ctx`: The rule context of the calling binary or test rule.
It must return a `struct` with the following fields:
* `additional_outputs`: Additional outputs expected from the linking action.
* `variables_extension`: A dictionary of additional crosstool variables to pass to the linking action. |
@@ -140,7 +142,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..708056e2b 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,8 +314,8 @@ bzl_library(
)
bzl_library(
- name = "wmo",
- srcs = ["wmo.bzl"],
+ name = "optimization",
+ srcs = ["optimization.bzl"],
visibility = ["//swift:__subpackages__"],
deps = [
":feature_names",
diff --git a/swift/internal/action_names.bzl b/swift/internal/action_names.bzl
index 3e2ae54c8..c4e379670 100644
--- a/swift/internal/action_names.bzl
+++ b/swift/internal/action_names.bzl
@@ -20,16 +20,20 @@
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"
-# Produces files that are usually fallout of the compilation such as
-# .swiftmodule, -Swift.h and more.
-SWIFT_ACTION_DERIVE_FILES = "SwiftDeriveFiles"
-
# Produces an AST file for each swift source file in a module.
SWIFT_ACTION_DUMP_AST = "SwiftDumpAST"
@@ -54,8 +58,9 @@ 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,
SWIFT_ACTION_MODULEWRAP,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
@@ -67,5 +72,6 @@ def all_compile_action_names():
"""Returns all actions that compile source files."""
return [
SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ SWIFT_ACTION_COMPILE_CODEGEN,
+ SWIFT_ACTION_COMPILE_MODULE,
]
diff --git a/swift/internal/actions.bzl b/swift/internal/actions.bzl
index f01d6d18d..dabc690f0 100644
--- a/swift/internal/actions.bzl
+++ b/swift/internal/actions.bzl
@@ -191,17 +191,7 @@ def run_toolchain_action(
# tool as the executable directly.
tools = []
tool_executable_args = actions.args()
- if tool_config.worker_mode:
- # Only enable persistent workers if the toolchain supports response
- # files, because the worker unconditionally writes its arguments into
- # one to prevent command line overflow in this mode.
- if (
- tool_config.worker_mode == "persistent" and
- tool_config.use_param_file
- ):
- execution_requirements["supports-workers"] = "1"
- execution_requirements["requires-worker-protocol"] = "json"
-
+ if tool_config.wrapped_by_worker:
executable = swift_toolchain.swift_worker
tool_executable_args.add(tool_config.executable)
if not types.is_string(tool_config.executable):
diff --git a/swift/internal/compiling.bzl b/swift/internal/compiling.bzl
index dfbd725cf..12b70f99b 100644
--- a/swift/internal/compiling.bzl
+++ b/swift/internal/compiling.bzl
@@ -28,8 +28,9 @@ 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",
"SWIFT_ACTION_PRECOMPILE_C_MODULE",
)
@@ -38,6 +39,7 @@ 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",
@@ -45,6 +47,7 @@ load(
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_EMIT_SWIFTINTERFACE",
"SWIFT_FEATURE_ENABLE_EMBEDDED",
+ "SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION",
"SWIFT_FEATURE_FULL_LTO",
"SWIFT_FEATURE_HEADERS_ALWAYS_ACTION_INPUTS",
"SWIFT_FEATURE_INDEX_WHILE_BUILDING",
@@ -52,14 +55,15 @@ 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",
"SWIFT_FEATURE_SYSTEM_MODULE",
"SWIFT_FEATURE_THIN_LTO",
"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(
@@ -70,6 +74,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",
@@ -82,7 +92,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.
@@ -456,18 +465,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
@@ -502,56 +499,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.indexstore_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.generated_header_file,
- compile_outputs.macro_expansion_directory,
- compile_outputs.swiftdoc_file,
- compile_outputs.swiftinterface_file,
- compile_outputs.private_swiftinterface_file,
- compile_outputs.swiftsourceinfo_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
@@ -648,64 +606,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
@@ -719,71 +674,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,
@@ -793,13 +717,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,
@@ -839,6 +763,411 @@ 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
+
+ # 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`.
+ """
+
+ 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
+
+ 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,
@@ -1157,13 +1486,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,
@@ -1178,9 +1506,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
@@ -1272,45 +1597,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(
@@ -1358,14 +1644,13 @@ 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:
- split_derived_file_generation = is_feature_enabled(
- feature_configuration = feature_configuration,
- feature_name = SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION,
- )
-
# If enabled the compiler will emit LLVM BC files instead of Mach-O object
# files.
# LTO implies emitting LLVM BC files, too
@@ -1392,7 +1677,6 @@ def _declare_compile_outputs(
extract_const_values = extract_const_values,
is_wmo = output_nature.is_wmo,
emits_bc = emits_bc,
- split_derived_file_generation = split_derived_file_generation,
srcs = srcs,
target_name = target_name,
include_index_unit_paths = include_index_unit_paths,
@@ -1402,6 +1686,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,
@@ -1417,7 +1702,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,
@@ -1429,7 +1713,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.
@@ -1462,7 +1765,6 @@ def _declare_multiple_outputs_and_write_output_file_map(
extract_const_values,
is_wmo,
emits_bc,
- split_derived_file_generation,
srcs,
target_name,
include_index_unit_paths):
@@ -1476,8 +1778,6 @@ def _declare_multiple_outputs_and_write_output_file_map(
requested.
emits_bc: If `True` the compiler will generate LLVM BC files instead of
object files.
- split_derived_file_generation: Whether objects and modules are produced
- by separate actions.
srcs: The list of source files that will be compiled.
target_name: The name (excluding package path) of the target being
built.
@@ -1502,12 +1802,15 @@ def _declare_multiple_outputs_and_write_output_file_map(
"{}.output_file_map.json".format(target_name),
)
- if split_derived_file_generation:
- derived_files_output_map_file = actions.declare_file(
- "{}.derived_output_file_map.json".format(target_name),
- )
- else:
- derived_files_output_map_file = None
+ # 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 = []
+
+ derived_files_output_map_file = None
# The output map data, which is keyed by source path and will be written to
# `output_map_file`.
@@ -1519,13 +1822,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 = {}
@@ -1562,18 +1858,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
@@ -1582,14 +1898,9 @@ def _declare_multiple_outputs_and_write_output_file_map(
output = output_map_file,
)
- if split_derived_file_generation:
- actions.write(
- content = "{}",
- output = derived_files_output_map_file,
- )
-
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 adc818fbd..4a4a6d434 100644
--- a/swift/internal/feature_names.bzl
+++ b/swift/internal/feature_names.bzl
@@ -190,6 +190,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.
@@ -327,15 +336,6 @@ SWIFT_FEATURE_GENERATE_FROM_RAW_PROTO_FILES = "swift.generate_from_raw_proto_fil
# generating a Swift file from a proto file.
SWIFT_FEATURE_GENERATE_PATH_TO_UNDERSCORES_FROM_PROTO_FILES = "swift.generate_path_to_underscores_from_proto_files"
-# If enabled and whole module optimisation is being used, the `*.swiftdoc`,
-# `*.swiftmodule` and `*-Swift.h` are generated with a separate action
-# rather than as part of the compilation.
-SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION = "swift.split_derived_files_generation"
-
-# If enabled the skip function bodies frontend flag is passed when using derived
-# files generation. This requires Swift 5.2
-SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES = "swift.skip_function_bodies_for_derived_files"
-
# If enabled remap the absolute path to Xcode in debug info. When used with
# swift.coverage_prefix_map also remap the path in coverage data.
SWIFT_FEATURE_REMAP_XCODE_PATH = "swift.remap_xcode_path"
@@ -364,6 +364,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"
@@ -386,6 +391,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 c618c0c46..77a25dc33 100644
--- a/swift/internal/features.bzl
+++ b/swift/internal/features.bzl
@@ -22,12 +22,12 @@ load(
"SWIFT_FEATURE_CHECKED_EXCLUSIVITY",
"SWIFT_FEATURE_COVERAGE",
"SWIFT_FEATURE_COVERAGE_PREFIX_MAP",
+ "SWIFT_FEATURE_DEBUG_PREFIX_MAP",
"SWIFT_FEATURE_DISABLE_CLANG_SPI",
"SWIFT_FEATURE_DISABLE_SYSTEM_INDEX",
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_ENABLE_BARE_SLASH_REGEX",
"SWIFT_FEATURE_ENABLE_BATCH_MODE",
- "SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES",
"SWIFT_FEATURE_ENABLE_TESTING",
"SWIFT_FEATURE_ENABLE_V6",
"SWIFT_FEATURE_FILE_PREFIX_MAP",
@@ -35,6 +35,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",
@@ -135,6 +136,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,
@@ -148,6 +162,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,
@@ -168,7 +183,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
@@ -176,19 +191,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.
@@ -249,12 +274,12 @@ def default_features_for_toolchain(target_triple):
SWIFT_FEATURE_CACHEABLE_SWIFTMODULES,
SWIFT_FEATURE_CHECKED_EXCLUSIVITY,
SWIFT_FEATURE_COVERAGE_PREFIX_MAP,
+ SWIFT_FEATURE_DEBUG_PREFIX_MAP,
SWIFT_FEATURE_DISABLE_CLANG_SPI,
SWIFT_FEATURE_DISABLE_SYSTEM_INDEX,
SWIFT_FEATURE_EMIT_SWIFTDOC,
SWIFT_FEATURE_ENABLE_BARE_SLASH_REGEX,
SWIFT_FEATURE_ENABLE_BATCH_MODE,
- SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES,
SWIFT_FEATURE_FILE_PREFIX_MAP,
SWIFT_FEATURE_INTERNALIZE_AT_LINK,
SWIFT_FEATURE_OPT_USES_WMO,
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/BUILD b/swift/toolchains/BUILD
index 54c959a4a..06b5e6b39 100644
--- a/swift/toolchains/BUILD
+++ b/swift/toolchains/BUILD
@@ -14,10 +14,10 @@ bzl_library(
"//swift/internal:debugging",
"//swift/internal:feature_names",
"//swift/internal:features",
+ "//swift/internal:optimization",
"//swift/internal:providers",
"//swift/internal:target_triples",
"//swift/internal:utils",
- "//swift/internal:wmo",
"//swift/toolchains/config:action_config",
"//swift/toolchains/config:all_actions_config",
"//swift/toolchains/config:compile_config",
@@ -42,10 +42,10 @@ bzl_library(
"//swift/internal:attrs",
"//swift/internal:feature_names",
"//swift/internal:features",
+ "//swift/internal:optimization",
"//swift/internal:providers",
"//swift/internal:target_triples",
"//swift/internal:utils",
- "//swift/internal:wmo",
"//swift/toolchains/config:action_config",
"//swift/toolchains/config:all_actions_config",
"//swift/toolchains/config:compile_config",
diff --git a/swift/toolchains/config/compile_config.bzl b/swift/toolchains/config/compile_config.bzl
index b5449fff5..db243ce4d 100644
--- a/swift/toolchains/config/compile_config.bzl
+++ b/swift/toolchains/config/compile_config.bzl
@@ -20,8 +20,9 @@ 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",
"SWIFT_ACTION_PRECOMPILE_C_MODULE",
"SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT",
@@ -59,7 +60,6 @@ load(
"SWIFT_FEATURE_ENABLE_CPP23_INTEROP",
"SWIFT_FEATURE_ENABLE_EMBEDDED",
"SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION",
- "SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES",
"SWIFT_FEATURE_ENABLE_TESTING",
"SWIFT_FEATURE_ENABLE_V6",
"SWIFT_FEATURE_FASTBUILD",
@@ -76,10 +76,10 @@ 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",
- "SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION",
"SWIFT_FEATURE_SUPPRESS_WARNINGS",
"SWIFT_FEATURE_SYSTEM_MODULE",
"SWIFT_FEATURE_THIN_LTO",
@@ -96,6 +96,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
@@ -104,14 +108,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 = [],
@@ -147,26 +143,29 @@ 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_DERIVE_FILES],
- configurators = [_output_swiftmodule_or_file_map_configurator],
+ actions = [
+ SWIFT_ACTION_COMPILE_CODEGEN,
+ SWIFT_ACTION_COMPILE_MODULE,
+ ],
+ configurators = [_compile_step_configurator],
),
# Dump ast files
@@ -210,12 +209,7 @@ def compile_action_configs(
# Configure the path to the emitted .swiftmodule file.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
- configurators = [_emit_module_path_configurator],
- not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
- ),
- ActionConfigInfo(
- actions = [SWIFT_ACTION_DERIVE_FILES],
+ actions = all_compile_action_names(),
configurators = [_emit_module_path_configurator],
),
@@ -228,14 +222,7 @@ def compile_action_configs(
ActionConfigInfo(
actions = [
SWIFT_ACTION_COMPILE,
- ],
- configurators = [_emit_module_interface_path_configurator],
- features = [SWIFT_FEATURE_EMIT_SWIFTINTERFACE],
- not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
- ),
- ActionConfigInfo(
- actions = [
- SWIFT_ACTION_DERIVE_FILES,
+ SWIFT_ACTION_COMPILE_MODULE,
],
configurators = [_emit_module_interface_path_configurator],
features = [SWIFT_FEATURE_EMIT_SWIFTINTERFACE],
@@ -243,14 +230,7 @@ def compile_action_configs(
ActionConfigInfo(
actions = [
SWIFT_ACTION_COMPILE,
- ],
- configurators = [_emit_private_module_interface_path_configurator],
- features = [SWIFT_FEATURE_EMIT_PRIVATE_SWIFTINTERFACE],
- not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
- ),
- ActionConfigInfo(
- actions = [
- SWIFT_ACTION_DERIVE_FILES,
+ SWIFT_ACTION_COMPILE_MODULE,
],
configurators = [_emit_private_module_interface_path_configurator],
features = [SWIFT_FEATURE_EMIT_PRIVATE_SWIFTINTERFACE],
@@ -258,12 +238,10 @@ def compile_action_configs(
# Configure the path to the emitted *-Swift.h file.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
- configurators = [_emit_objc_header_path_configurator],
- not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
- ),
- ActionConfigInfo(
- actions = [SWIFT_ACTION_DERIVE_FILES],
+ actions = [
+ SWIFT_ACTION_COMPILE,
+ SWIFT_ACTION_COMPILE_MODULE,
+ ],
configurators = [_emit_objc_header_path_configurator],
),
@@ -276,7 +254,7 @@ def compile_action_configs(
# Configure constant value extraction.
ActionConfigInfo(
- actions = [SWIFT_ACTION_COMPILE],
+ actions = all_compile_action_names(),
configurators = [_constant_value_extraction_configurator],
),
@@ -314,16 +292,7 @@ def compile_action_configs(
ActionConfigInfo(
actions = [
SWIFT_ACTION_COMPILE,
- ],
- configurators = [generated_header_rewriter_configurator],
- features = [SWIFT_FEATURE_REWRITE_GENERATED_HEADER],
- not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
- ),
- )
- action_configs.append(
- ActionConfigInfo(
- actions = [
- SWIFT_ACTION_DERIVE_FILES,
+ SWIFT_ACTION_COMPILE_MODULE,
],
configurators = [generated_header_rewriter_configurator],
features = [SWIFT_FEATURE_REWRITE_GENERATED_HEADER],
@@ -379,6 +348,11 @@ def compile_action_configs(
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.
@@ -430,9 +404,7 @@ def compile_action_configs(
# Enable suppress-warnings if requested.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
],
configurators = [
@@ -443,9 +415,7 @@ def compile_action_configs(
# Enable warnings-as-errors if requested.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
],
configurators = [
@@ -456,9 +426,7 @@ def compile_action_configs(
# Disable Swift sandbox.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
],
configurators = [
@@ -469,9 +437,7 @@ def compile_action_configs(
# Set Developer Framework search paths
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
],
@@ -573,17 +539,7 @@ def compile_action_configs(
# Ensure that .swiftsourceinfo files are tracked and not deleted by the worker
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
- configurators = [add_arg("-Xwrapped-swift=-emit-swiftsourceinfo")],
- features = [SWIFT_FEATURE_DECLARE_SWIFTSOURCEINFO],
- not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
- ),
- ActionConfigInfo(
- actions = [
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [add_arg("-Xwrapped-swift=-emit-swiftsourceinfo")],
features = [SWIFT_FEATURE_DECLARE_SWIFTSOURCEINFO],
),
@@ -636,10 +592,7 @@ def compile_action_configs(
action_configs.append(
# Support for order-file instrumentation.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-sanitize=undefined"),
add_arg("-sanitize-coverage=func"),
@@ -660,7 +613,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", "."),
],
@@ -715,10 +670,8 @@ 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,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -734,10 +687,8 @@ 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,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
],
@@ -749,10 +700,8 @@ 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,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
],
@@ -764,10 +713,8 @@ 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,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
],
@@ -780,9 +727,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
],
configurators = [_pch_output_dir_configurator],
@@ -793,10 +738,8 @@ 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,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -807,8 +750,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,
@@ -849,9 +791,7 @@ def compile_action_configs(
#### Search paths/explicit module map for Swift module dependencies
action_configs.extend([
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
],
configurators = [
@@ -878,10 +818,8 @@ 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,
],
configurators = [_dependencies_swiftmodules_configurator],
@@ -891,9 +829,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
],
configurators = [
@@ -913,35 +849,19 @@ def compile_action_configs(
features = [SWIFT_FEATURE_VFSOVERLAY],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [_module_aliases_configurator],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
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,
- ],
- configurators = [_macro_expansion_configurator],
- # The compiler only generates these in debug builds, unless we pass
- # additional frontend flags. At the current time, we only want to
- # capture these for debug builds.
- not_features = [
- [SWIFT_FEATURE_OPT],
- [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION],
- ],
- ),
- ActionConfigInfo(
- actions = [
- SWIFT_ACTION_DERIVE_FILES,
+ SWIFT_ACTION_COMPILE_MODULE,
],
configurators = [_macro_expansion_configurator],
# The compiler only generates these in debug builds, unless we pass
@@ -950,10 +870,7 @@ def compile_action_configs(
not_features = [SWIFT_FEATURE_OPT],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [_plugin_search_paths_configurator],
),
@@ -980,10 +897,8 @@ 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,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
SWIFT_ACTION_SYNTHESIZE_INTERFACE,
@@ -1012,10 +927,8 @@ 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,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -1030,10 +943,8 @@ 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,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
SWIFT_ACTION_SYNTHESIZE_INTERFACE,
@@ -1042,10 +953,8 @@ 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,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -1074,9 +983,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,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
configurators = [add_arg("-Xfrontend", "-color-diagnostics")],
@@ -1097,8 +1004,10 @@ 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,
],
configurators = [_batch_mode_configurator],
features = [SWIFT_FEATURE_ENABLE_BATCH_MODE],
@@ -1112,10 +1021,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,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [
_make_wmo_thread_count_configurator(
# WMO is implied by features, so don't check the user
@@ -1131,10 +1037,7 @@ def compile_action_configs(
not_features = [SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [
_make_wmo_thread_count_configurator(
# WMO is not implied by features, so check the user compile
@@ -1150,9 +1053,7 @@ def compile_action_configs(
# Set the module name.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -1163,36 +1064,21 @@ def compile_action_configs(
# Set the package name.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
configurators = [_package_name_configurator],
),
- # Extra flags for swiftmodule only compilations.
- ActionConfigInfo(
- actions = [SWIFT_ACTION_DERIVE_FILES],
- configurators = [
- add_arg("-experimental-skip-non-inlinable-function-bodies"),
- ],
- features = [SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES],
- ),
-
# 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,
@@ -1200,9 +1086,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,
@@ -1210,9 +1094,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-index-ignore-clang-modules"),
],
@@ -1239,7 +1121,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,
@@ -1249,67 +1131,48 @@ def compile_action_configs(
# Disable auto-linking for prebuilt static frameworks.
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ 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,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
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,
],
configurators = [add_arg("-enable-bare-slash-regex")],
features = [SWIFT_FEATURE_ENABLE_BARE_SLASH_REGEX],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [add_arg("-Xfrontend", "-disable-clang-spi")],
features = [
SWIFT_FEATURE_DISABLE_CLANG_SPI,
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [add_arg("-Xfrontend", "-disable-availability-checking")],
features = [
SWIFT_FEATURE_DISABLE_AVAILABILITY_CHECKING,
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [_upcoming_and_experimental_features_configurator],
features = [
SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES,
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
- ],
+ actions = all_compile_action_names(),
configurators = [add_arg("-swift-version", "6")],
features = [
SWIFT_FEATURE_ENABLE_V6,
@@ -1317,9 +1180,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-cxx-interoperability-mode=default"),
add_arg("-Xcc", "-std=c++17"),
@@ -1329,9 +1190,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-cxx-interoperability-mode=default"),
add_arg("-Xcc", "-std=c++20"),
@@ -1341,9 +1200,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-cxx-interoperability-mode=default"),
add_arg("-Xcc", "-std=c++23"),
@@ -1353,9 +1210,7 @@ def compile_action_configs(
],
),
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- ],
+ actions = all_compile_action_names(),
configurators = [
add_arg("-enable-experimental-feature", "Embedded"),
],
@@ -1373,10 +1228,8 @@ 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,
],
configurators = [_user_compile_flags_configurator],
@@ -1385,10 +1238,8 @@ 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,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -1408,10 +1259,8 @@ 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,
],
configurators = [
@@ -1442,27 +1291,21 @@ def compile_action_configs(
),
)
- action_configs.extend(
- [
- ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
- SWIFT_ACTION_DERIVE_FILES,
- SWIFT_ACTION_DUMP_AST,
- SWIFT_ACTION_PRECOMPILE_C_MODULE,
- ],
- configurators = [_source_files_configurator],
- ),
- ],
+ action_configs.append(
+ ActionConfigInfo(
+ actions = all_compile_action_names() + [
+ SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
+ SWIFT_ACTION_DUMP_AST,
+ SWIFT_ACTION_PRECOMPILE_C_MODULE,
+ ],
+ configurators = [_source_files_configurator],
+ ),
)
# Add additional input files to the sandbox (does not modify flags).
action_configs.append(
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
],
configurators = [_additional_inputs_configurator],
@@ -1543,14 +1386,6 @@ def _output_object_or_file_map_configurator(prerequisites, args):
args = args,
)
-def _output_swiftmodule_or_file_map_configurator(prerequisites, args):
- """Adds the output file map or single object file to the command line."""
- return _output_or_file_map(
- output_file_map = prerequisites.derived_files_output_file_map,
- outputs = [prerequisites.swiftmodule_file],
- args = args,
- )
-
def _output_ast_path_or_file_map_configurator(prerequisites, args):
"""Adds the output file map or single AST file to the command line."""
return _output_or_file_map(
@@ -1559,6 +1394,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)
@@ -1666,7 +1509,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):
@@ -2254,25 +2097,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/config/tool_config.bzl b/swift/toolchains/config/tool_config.bzl
index fbeacf8b0..f73ffbaff 100644
--- a/swift/toolchains/config/tool_config.bzl
+++ b/swift/toolchains/config/tool_config.bzl
@@ -26,7 +26,7 @@ def _tool_config_info_init(
execution_requirements = {},
resource_set = None,
use_param_file = False,
- worker_mode = None):
+ wrapped_by_worker = False):
"""Validates and initializes a new Swift toolchain tool configuration.
The `driver_config` argument can be specified as a convenience that supports
@@ -65,22 +65,20 @@ def _tool_config_info_init(
invoking actions using this tool.
executable: The `File` or `string` denoting the tool that should be
executed. This will be used as the `executable` argument of spawned
- actions unless `worker_mode` is set, in which case it will be used
- as the first argument to the worker.
+ actions unless `wrapped_by_worker` is True, in which case it will be
+ used as the first argument to the worker.
execution_requirements: A dictionary of execution requirements that
should be passed when creating actions with this tool.
resource_set: The function which build resource set (mem, cpu) for local
invocation of the action.
use_param_file: If True, actions invoked using this tool will have their
arguments written to a param file.
- worker_mode: A string, or `None`, describing how the tool is invoked
- using the build rules' worker, if at all. If `None`, the tool will
- be invoked directly. If `"wrap"`, the tool will be wrapped in an
- invocation of the worker but otherwise run as a single process. If
- `"persistent"`, then the action will be launched with execution
- requirements that indicate that Bazel should attempt to use a
- persistent worker if the spawn strategy allows for it (starting a
- new instance if necessary, or connecting to an existing one).
+ wrapped_by_worker: A Boolean value indicating whether the tool should be
+ wrapped inside an invocation of the build rules' worker process. If
+ False, the tool will be invoked directly. (The term "worker" is an
+ artifact from when a persistent worker was supported by the rules.
+ This is no longer the case; now "worker" just means the executable
+ that wraps Swift compiler invocations.)
Returns:
A validated dictionary with the fields of the `ToolConfigInfo` provider.
@@ -119,7 +117,7 @@ def _tool_config_info_init(
"execution_requirements": execution_requirements,
"resource_set": resource_set,
"use_param_file": use_param_file,
- "worker_mode": _validate_worker_mode(worker_mode),
+ "wrapped_by_worker": wrapped_by_worker,
}
ToolConfigInfo, _tool_config_info_init_unchecked = provider(
@@ -132,28 +130,7 @@ ToolConfigInfo, _tool_config_info_init_unchecked = provider(
"execution_requirements",
"resource_set",
"use_param_file",
- "worker_mode",
+ "wrapped_by_worker",
],
init = _tool_config_info_init,
)
-
-def _validate_worker_mode(worker_mode):
- """Validates the `worker_mode` argument of `tool_config`.
-
- This function fails the build if the worker mode is not None, "persistent",
- or "wrap".
-
- Args:
- worker_mode: The worker mode to validate.
-
- Returns:
- The original worker mode, if it was valid.
- """
- if worker_mode != None and worker_mode not in ("persistent", "wrap"):
- fail(
- "The 'worker_mode' argument of " +
- "'swift_toolchain_config.tool_config' must be either None, " +
- "'persistent', or 'wrap'.",
- )
-
- return worker_mode
diff --git a/swift/toolchains/swift_toolchain.bzl b/swift/toolchains/swift_toolchain.bzl
index 462c44a7e..3d52e11f4 100644
--- a/swift/toolchains/swift_toolchain.bzl
+++ b/swift/toolchains/swift_toolchain.bzl
@@ -39,8 +39,9 @@ load(
"//swift/internal:action_names.bzl",
"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",
"SWIFT_ACTION_MODULEWRAP",
"SWIFT_ACTION_PRECOMPILE_C_MODULE",
@@ -61,6 +62,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",
@@ -72,7 +74,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",
@@ -142,19 +143,20 @@ def _all_tool_configs(
driver_config = _driver_config(mode = "swiftc"),
resource_set = _swift_compile_resource_set,
use_param_file = True,
- worker_mode = "persistent",
+ wrapped_by_worker = True,
env = env,
)
tool_configs = {
SWIFT_ACTION_COMPILE: compile_tool_config,
- SWIFT_ACTION_DERIVE_FILES: compile_tool_config,
+ SWIFT_ACTION_COMPILE_CODEGEN: compile_tool_config,
+ SWIFT_ACTION_COMPILE_MODULE: compile_tool_config,
SWIFT_ACTION_DUMP_AST: compile_tool_config,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT: ToolConfigInfo(
additional_tools = additional_tools,
driver_config = _driver_config(mode = "swift-symbolgraph-extract"),
use_param_file = True,
- worker_mode = "wrap",
+ wrapped_by_worker = True,
env = env,
),
}
@@ -163,7 +165,7 @@ def _all_tool_configs(
tool_configs[SWIFT_ACTION_AUTOLINK_EXTRACT] = ToolConfigInfo(
additional_tools = additional_tools,
driver_config = _driver_config(mode = "swift-autolink-extract"),
- worker_mode = "wrap",
+ wrapped_by_worker = True,
)
if use_module_wrap:
@@ -172,7 +174,7 @@ def _all_tool_configs(
# This must come first after the driver name.
args = ["-modulewrap"],
driver_config = _driver_config(mode = "swift"),
- worker_mode = "wrap",
+ wrapped_by_worker = True,
)
return tool_configs
@@ -199,7 +201,6 @@ def _all_action_configs(os, arch, target_triple, sdkroot, xctest_version, additi
actions = [
SWIFT_ACTION_COMPILE,
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
- SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_MODULEWRAP,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
@@ -216,7 +217,6 @@ def _all_action_configs(os, arch, target_triple, sdkroot, xctest_version, additi
ActionConfigInfo(
actions = [
SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
@@ -229,7 +229,6 @@ def _all_action_configs(os, arch, target_triple, sdkroot, xctest_version, additi
ActionConfigInfo(
actions = [
SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
@@ -258,7 +257,6 @@ def _all_action_configs(os, arch, target_triple, sdkroot, xctest_version, additi
ActionConfigInfo(
actions = [
SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
],
@@ -465,9 +463,13 @@ def _swift_toolchain_impl(ctx):
# Combine build mode features, autoconfigured features, and required
# features.
+ requested_build_mode_features, _ = features_for_build_modes(ctx)
+ requested_optimization_features, _ = optimization_features_from_swiftcopts(
+ swiftcopts = swiftcopts,
+ )
requested_features = (
- features_for_build_modes(ctx) +
- features_from_swiftcopts(swiftcopts = swiftcopts)
+ requested_build_mode_features +
+ requested_optimization_features
)
requested_features.extend(default_features_for_toolchain(
target_triple = target_triple,
@@ -534,6 +536,7 @@ def _swift_toolchain_impl(ctx):
clang_implicit_deps_providers = (
collect_implicit_deps_providers([])
),
+ codegen_batch_size = 8,
cross_import_overlays = [
target[SwiftCrossImportOverlayInfo]
for target in ctx.attr.cross_import_overlays
diff --git a/swift/toolchains/xcode_swift_toolchain.bzl b/swift/toolchains/xcode_swift_toolchain.bzl
index 79699cea2..733eea65c 100644
--- a/swift/toolchains/xcode_swift_toolchain.bzl
+++ b/swift/toolchains/xcode_swift_toolchain.bzl
@@ -39,8 +39,9 @@ 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_MODULEWRAP",
"SWIFT_ACTION_PRECOMPILE_C_MODULE",
@@ -68,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",
@@ -80,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",
@@ -431,10 +435,8 @@ 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,
SWIFT_ACTION_MODULEWRAP,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
@@ -469,7 +471,6 @@ def _all_action_configs(
actions = all_compile_action_names() + [
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_COMPILE_MODULE_INTERFACE,
- SWIFT_ACTION_DERIVE_FILES,
],
configurators = [
add_arg(
@@ -509,9 +510,7 @@ def _all_action_configs(
# directory so that modules are found correctly.
action_configs.append(
ActionConfigInfo(
- actions = [
- SWIFT_ACTION_COMPILE,
- SWIFT_ACTION_DERIVE_FILES,
+ actions = all_compile_action_names() + [
SWIFT_ACTION_DUMP_AST,
SWIFT_ACTION_PRECOMPILE_C_MODULE,
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT,
@@ -607,12 +606,13 @@ def _all_tool_configs(
execution_requirements = execution_requirements,
resource_set = _swift_compile_resource_set,
use_param_file = True,
- worker_mode = "persistent",
+ wrapped_by_worker = True,
)
tool_configs = {
SWIFT_ACTION_COMPILE: tool_config,
- SWIFT_ACTION_DERIVE_FILES: tool_config,
+ SWIFT_ACTION_COMPILE_CODEGEN: tool_config,
+ SWIFT_ACTION_COMPILE_MODULE: tool_config,
SWIFT_ACTION_DUMP_AST: tool_config,
SWIFT_ACTION_PRECOMPILE_C_MODULE: (
ToolConfigInfo(
@@ -620,7 +620,7 @@ def _all_tool_configs(
env = env,
execution_requirements = execution_requirements,
use_param_file = True,
- worker_mode = "wrap",
+ wrapped_by_worker = True,
)
),
SWIFT_ACTION_COMPILE_MODULE_INTERFACE: (
@@ -631,7 +631,7 @@ def _all_tool_configs(
execution_requirements = execution_requirements,
resource_set = _swift_compile_resource_set,
use_param_file = True,
- worker_mode = "wrap",
+ wrapped_by_worker = True,
)
),
SWIFT_ACTION_SYMBOL_GRAPH_EXTRACT: (
@@ -642,7 +642,7 @@ def _all_tool_configs(
env = env,
execution_requirements = execution_requirements,
use_param_file = True,
- worker_mode = "wrap",
+ wrapped_by_worker = True,
)
),
}
@@ -654,7 +654,7 @@ def _all_tool_configs(
env = env,
execution_requirements = execution_requirements,
use_param_file = True,
- worker_mode = "wrap",
+ wrapped_by_worker = True,
)
return tool_configs
@@ -790,10 +790,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 = ctx.attr.copts + swiftcopts)
+ requested_features, unsupported_features = (
+ optimization_features_from_swiftcopts(swiftcopts = ctx.attr.copts + 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(
@@ -827,9 +833,12 @@ def _xcode_swift_toolchain_impl(ctx):
])
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)
@@ -895,6 +904,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
@@ -1088,8 +1098,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 5929d0850..a7539391e 100644
--- a/test/BUILD
+++ b/test/BUILD
@@ -17,11 +17,11 @@ 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")
load(":runtime_deps_tests.bzl", "runtime_deps_test_suite")
-load(":split_derived_files_tests.bzl", "split_derived_files_test_suite")
load(":swift_binary_linking_tests.bzl", "swift_binary_linking_test_suite")
load(":swift_through_non_swift_tests.bzl", "swift_through_non_swift_test_suite")
load(":symbol_graphs_tests.bzl", "symbol_graphs_test_suite")
@@ -67,8 +67,6 @@ output_file_map_test_suite(name = "output_file_map")
private_deps_test_suite(name = "private_deps")
-split_derived_files_test_suite(name = "split_derived_files")
-
swift_binary_linking_test_suite(name = "swift_binary_rules")
swift_through_non_swift_test_suite(name = "swift_through_non_swift")
@@ -83,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/compiler_arguments_tests.bzl b/test/compiler_arguments_tests.bzl
index abe7964aa..55ee05105 100644
--- a/test/compiler_arguments_tests.bzl
+++ b/test/compiler_arguments_tests.bzl
@@ -6,14 +6,6 @@ load(
"make_action_command_line_test_rule",
)
-split_test = make_action_command_line_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "swift.split_derived_files_generation",
- ],
- },
-)
-
thin_lto_test = make_action_command_line_test_rule(
config_settings = {
"//command_line_option:features": [
@@ -71,22 +63,6 @@ def compiler_arguments_test_suite(name, tags = []):
target_under_test = "//test/fixtures/compiler_arguments:test_package_name",
)
- split_test(
- name = "{}_split_lib_with_package".format(name),
- expected_argv = ["-package-name lib"],
- mnemonic = "SwiftCompile",
- tags = all_tags,
- target_under_test = "//test/fixtures/compiler_arguments:lib_package_name",
- )
-
- split_test(
- name = "{}_split_module_with_package".format(name),
- expected_argv = ["-package-name lib"],
- mnemonic = "SwiftDeriveFiles",
- tags = all_tags,
- target_under_test = "//test/fixtures/compiler_arguments:lib_package_name",
- )
-
thin_lto_test(
name = "{}_thin_lto".format(name),
expected_argv = ["-lto=llvm-thin"],
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 92dc95dd4..bee387cd6 100644
--- a/test/debug_settings_tests.bzl
+++ b/test/debug_settings_tests.bzl
@@ -26,6 +26,14 @@ DBG_CONFIG_SETTINGS = {
],
}
+FILE_PREFIX_MAP_CONFIG_SETTINGS = {
+ "//command_line_option:compilation_mode": "dbg",
+ "//command_line_option:features": [
+ "swift.debug_prefix_map",
+ "swift.file_prefix_map",
+ ],
+}
+
CACHEABLE_DBG_CONFIG_SETTINGS = {
"//command_line_option:compilation_mode": "dbg",
"//command_line_option:features": [
@@ -67,6 +75,10 @@ dbg_action_command_line_test = make_action_command_line_test_rule(
config_settings = DBG_CONFIG_SETTINGS,
)
+file_prefix_map_command_line_test = make_action_command_line_test_rule(
+ config_settings = FILE_PREFIX_MAP_CONFIG_SETTINGS,
+)
+
cacheable_dbg_action_command_line_test = make_action_command_line_test_rule(
config_settings = CACHEABLE_DBG_CONFIG_SETTINGS,
)
@@ -120,9 +132,22 @@ def debug_settings_test_suite(name, tags = []):
"-DNDEBUG",
"-Xfrontend -no-serialize-debugging-options",
"-gline-tables-only",
+ ],
+ mnemonic = "SwiftCompileModule",
+ tags = all_tags,
+ target_under_test = "//test/fixtures/debug_settings:simple",
+ )
+
+ # Verify that the build is remapping paths with a file prefix map.
+ file_prefix_map_command_line_test(
+ name = "{}_file_prefix_map_build".format(name),
+ expected_argv = [
+ "-Xwrapped-swift=-file-prefix-pwd-is-dot",
+ ],
+ 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",
)
@@ -144,7 +169,7 @@ def debug_settings_test_suite(name, tags = []):
"-gline-tables-only",
"-Xwrapped-swift=-debug-prefix-pwd-is-dot",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -165,7 +190,7 @@ def debug_settings_test_suite(name, tags = []):
"-g",
"-Xwrapped-swift=-debug-prefix-pwd-is-dot",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -186,7 +211,7 @@ def debug_settings_test_suite(name, tags = []):
"-gline-tables-only",
"-Xwrapped-swift=-debug-prefix-pwd-is-dot",
],
- mnemonic = "SwiftCompile",
+ mnemonic = "SwiftCompileModule",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)
@@ -223,6 +248,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",
@@ -235,7 +262,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 0ac3409d4..cfcbd2c3c 100644
--- a/test/features_tests.bzl
+++ b/test/features_tests.bzl
@@ -157,7 +157,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",
)
@@ -170,7 +170,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",
)
@@ -180,7 +180,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",
)
@@ -190,7 +190,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",
)
@@ -201,7 +201,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",
)
@@ -210,6 +210,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",
)
@@ -219,7 +221,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..96c61d29d 100644
--- a/test/fixtures/debug_settings/BUILD
+++ b/test/fixtures/debug_settings/BUILD
@@ -16,5 +16,10 @@ 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,
)
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
deleted file mode 100644
index b53c7cbd6..000000000
--- a/test/split_derived_files_tests.bzl
+++ /dev/null
@@ -1,503 +0,0 @@
-"""Tests for derived files related command line flags under various configs."""
-
-load(
- "//test/rules:action_command_line_test.bzl",
- "make_action_command_line_test_rule",
-)
-load("//test/rules:provider_test.bzl", "make_provider_test_rule")
-
-default_no_split_test = make_action_command_line_test_rule()
-default_no_split_provider_test = make_provider_test_rule()
-
-default_no_split_no_emit_swiftdoc_provider_test = make_provider_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "-swift.emit_swiftdoc",
- ],
- },
-)
-
-default_no_split_emit_swiftsourceinfo_provider_test = make_provider_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "swift.emit_swiftsourceinfo",
- ],
- },
-)
-
-split_swiftmodule_test = make_action_command_line_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "swift.split_derived_files_generation",
- ],
- },
-)
-split_swiftmodule_provider_test = make_provider_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "swift.split_derived_files_generation",
- ],
- },
-)
-
-split_swiftmodule_skip_function_bodies_test = make_action_command_line_test_rule(
- config_settings = {
- str(Label("//swift:copt")): [
- "-whole-module-optimization",
- ],
- "//command_line_option:features": [
- "swift.split_derived_files_generation",
- "swift.enable_skip_function_bodies",
- ],
- },
-)
-
-split_emit_swiftsourceinfo_provider_test = make_provider_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "swift.emit_swiftsourceinfo",
- "swift.split_derived_files_generation",
- ],
- },
-)
-
-split_no_emit_swiftdoc_provider_test = make_provider_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "-swift.emit_swiftdoc",
- "swift.split_derived_files_generation",
- ],
- },
-)
-
-split_swiftmodule_bitcode_test = make_action_command_line_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "swift.split_derived_files_generation",
- "swift.emit_bc",
- ],
- },
-)
-
-split_swiftmodule_copts_test = make_action_command_line_test_rule(
- config_settings = {
- str(Label("//swift:copt")): [
- "-DHELLO",
- ],
- "//command_line_option:objccopt": [
- "-DWORLD=1",
- ],
- "//command_line_option:features": [
- "swift.split_derived_files_generation",
- ],
- },
-)
-
-split_swiftmodule_indexing_test = make_action_command_line_test_rule(
- config_settings = {
- "//command_line_option:features": [
- "swift.index_while_building",
- "swift.split_derived_files_generation",
- ],
- },
-)
-
-split_swiftmodule_wmo_test = make_action_command_line_test_rule(
- config_settings = {
- str(Label("//swift:copt")): [
- "-whole-module-optimization",
- ],
- "//command_line_option:features": [
- "swift.split_derived_files_generation",
- ],
- },
-)
-split_swiftmodule_wmo_provider_test = make_provider_test_rule(
- config_settings = {
- str(Label("//swift:copt")): [
- "-whole-module-optimization",
- ],
- "//command_line_option:features": [
- "swift.split_derived_files_generation",
- ],
- },
-)
-
-def split_derived_files_test_suite(name, tags = []):
- """Test suite for split derived files options.
-
- 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
-
- default_no_split_test(
- name = "{}_default_no_split_args".format(name),
- expected_argv = [
- "-emit-module-path",
- "-emit-object",
- "-enable-batch-mode",
- "simple.output_file_map.json",
- ],
- not_expected_argv = [
- "simple.derived_output_file_map.json",
- ],
- mnemonic = "SwiftCompile",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- default_no_split_provider_test(
- name = "{}_default_no_split_provider_swiftmodule".format(name),
- expected_files = [
- "test_fixtures_debug_settings_simple.swiftmodule",
- ],
- field = "direct_modules.swift.swiftmodule",
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- default_no_split_provider_test(
- name = "{}_default_no_split_provider_swiftdoc".format(name),
- expected_files = [
- "test_fixtures_debug_settings_simple.swiftdoc",
- ],
- field = "direct_modules.swift.swiftdoc",
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- default_no_split_emit_swiftsourceinfo_provider_test(
- name = "{}_default_no_split_provider_swiftsourceinfo".format(name),
- expected_files = [
- "test_fixtures_debug_settings_simple.swiftsourceinfo",
- ],
- field = "direct_modules.swift.swiftsourceinfo",
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- default_no_split_no_emit_swiftdoc_provider_test(
- name = "{}_default_no_split_provider_no_emit_swiftdoc".format(name),
- expected_files = [
- "-test_fixtures_debug_settings_simple.swiftdoc",
- ],
- field = "direct_modules.swift.swiftdoc",
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- default_no_split_provider_test(
- name = "{}_default_no_split_provider_no_emit_swiftsourceinfo".format(name),
- expected_files = [
- "-test_fixtures_debug_settings_simple.swiftsourceinfo",
- ],
- field = "direct_modules.swift.swiftsourceinfo",
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_provider_test(
- name = "{}_split_provider_swiftdoc".format(name),
- field = "direct_modules.swift.swiftdoc",
- expected_files = [
- "test_fixtures_debug_settings_simple.swiftdoc",
- ],
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_emit_swiftsourceinfo_provider_test(
- name = "{}_split_provider_swiftsourceinfo".format(name),
- field = "direct_modules.swift.swiftsourceinfo",
- expected_files = [
- "test_fixtures_debug_settings_simple.swiftsourceinfo",
- ],
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_no_emit_swiftdoc_provider_test(
- name = "{}_split_provider_no_emit_swiftdoc".format(name),
- field = "direct_modules.swift.swiftdoc",
- expected_files = [
- "-test_fixtures_debug_settings_simple.swiftdoc",
- ],
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_provider_test(
- name = "{}_split_provider_no_emit_swiftsourceinfo".format(name),
- field = "direct_modules.swift.swiftsourceinfo",
- expected_files = [
- "-test_fixtures_debug_settings_simple.swiftsourceinfo",
- ],
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- default_no_split_provider_test(
- name = "{}_default_no_split_provider_ccinfo".format(name),
- expected_files = [
- "libsimple.a",
- ],
- field = "linking_context.linker_inputs.libraries.static_library!",
- provider = "CcInfo",
- tags = all_tags,
- target_compatible_with = ["@platforms//os:macos"],
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- default_no_split_provider_test(
- name = "{}_default_no_split_provider_ccinfo_linux".format(name),
- expected_files = [
- "libsimple.a",
- ],
- field = "linking_context.linker_inputs.libraries.pic_static_library!",
- provider = "CcInfo",
- tags = all_tags,
- target_compatible_with = ["@platforms//os:linux"],
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_test(
- name = "{}_object_only".format(name),
- expected_argv = [
- "-emit-object",
- "-enable-batch-mode",
- "simple.output_file_map.json",
- ],
- mnemonic = "SwiftCompile",
- not_expected_argv = [
- "-emit-module-path",
- "simple.derived_output_file_map.json",
- ],
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_test(
- name = "{}_swiftmodule_only".format(name),
- expected_argv = [
- "-emit-module-path",
- "-enable-batch-mode",
- "simple.derived_output_file_map.json",
- ],
- mnemonic = "SwiftDeriveFiles",
- not_expected_argv = [
- "-emit-object",
- "simple.output_file_map.json",
- ],
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_provider_test(
- name = "{}_split_provider".format(name),
- expected_files = [
- "test_fixtures_debug_settings_simple.swiftmodule",
- ],
- field = "direct_modules.swift.swiftmodule",
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_provider_test(
- name = "{}_split_provider_ccinfo".format(name),
- expected_files = [
- "libsimple.a",
- ],
- field = "linking_context.linker_inputs.libraries.static_library!",
- provider = "CcInfo",
- tags = all_tags,
- target_compatible_with = ["@platforms//os:macos"],
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_provider_test(
- name = "{}_split_provider_ccinfo_linux".format(name),
- expected_files = [
- "libsimple.a",
- ],
- field = "linking_context.linker_inputs.libraries.pic_static_library!",
- provider = "CcInfo",
- tags = all_tags,
- target_compatible_with = ["@platforms//os:linux"],
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_wmo_test(
- name = "{}_object_only_wmo".format(name),
- expected_argv = [
- "-emit-object",
- "-whole-module-optimization",
- ],
- mnemonic = "SwiftCompile",
- not_expected_argv = [
- "-emit-module-path",
- ],
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_wmo_test(
- name = "{}_swiftmodule_only_wmo".format(name),
- expected_argv = [
- "-emit-module-path",
- "-whole-module-optimization",
- ],
- mnemonic = "SwiftDeriveFiles",
- not_expected_argv = [
- "-emit-object",
- ],
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_wmo_provider_test(
- name = "{}_split_wmo_provider".format(name),
- expected_files = [
- "test_fixtures_debug_settings_simple.swiftmodule",
- ],
- field = "direct_modules.swift.swiftmodule",
- provider = "SwiftInfo",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_wmo_provider_test(
- name = "{}_split_wmo_provider_ccinfo".format(name),
- expected_files = [
- "libsimple.a",
- ],
- field = "linking_context.linker_inputs.libraries.static_library!",
- provider = "CcInfo",
- tags = all_tags,
- target_compatible_with = ["@platforms//os:macos"],
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_wmo_provider_test(
- name = "{}_split_wmo_provider_ccinfo_linux".format(name),
- expected_files = [
- "libsimple.a",
- ],
- field = "linking_context.linker_inputs.libraries.pic_static_library!",
- provider = "CcInfo",
- tags = all_tags,
- target_compatible_with = ["@platforms//os:linux"],
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_skip_function_bodies_test(
- name = "{}_no_skip_function_bodies".format(name),
- expected_argv = [
- "-emit-object",
- ],
- mnemonic = "SwiftCompile",
- not_expected_argv = [
- "-experimental-skip-non-inlinable-function-bodies",
- ],
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_skip_function_bodies_test(
- name = "{}_skip_function_bodies".format(name),
- expected_argv = [
- "-experimental-skip-non-inlinable-function-bodies",
- ],
- mnemonic = "SwiftDeriveFiles",
- not_expected_argv = [
- "-emit-object",
- ],
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_indexing_test(
- name = "{}_object_only_indexing".format(name),
- expected_argv = [
- "-emit-object",
- "-index-store-path",
- ],
- mnemonic = "SwiftCompile",
- not_expected_argv = [
- "-emit-module-path",
- ],
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_indexing_test(
- name = "{}_swiftmodule_only_indexing".format(name),
- expected_argv = [
- "-emit-module-path",
- ],
- mnemonic = "SwiftDeriveFiles",
- not_expected_argv = [
- "-emit-object",
- "-index-store-path",
- ],
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_bitcode_test(
- name = "{}_bitcode_compile".format(name),
- expected_argv = ["-emit-bc"],
- mnemonic = "SwiftCompile",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_bitcode_test(
- name = "{}_bitcode_derive_files".format(name),
- not_expected_argv = [
- "-emit-bc",
- ],
- mnemonic = "SwiftDeriveFiles",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_copts_test(
- name = "{}_copts_compile".format(name),
- expected_argv = [
- "-DHELLO",
- "-Xcc -DWORLD=1",
- ],
- target_compatible_with = ["@platforms//os:macos"],
- mnemonic = "SwiftCompile",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- split_swiftmodule_copts_test(
- name = "{}_copts_derive_files".format(name),
- expected_argv = [
- "-DHELLO",
- "-Xcc -DWORLD=1",
- ],
- target_compatible_with = ["@platforms//os:macos"],
- mnemonic = "SwiftDeriveFiles",
- tags = all_tags,
- target_under_test = "//test/fixtures/debug_settings:simple",
- )
-
- native.test_suite(
- name = name,
- tags = all_tags,
- )
diff --git a/tools/common/BUILD b/tools/common/BUILD
index 1958be7bd..5172ffa9f 100644
--- a/tools/common/BUILD
+++ b/tools/common/BUILD
@@ -38,6 +38,11 @@ cc_library(
"-std=c++17",
],
}),
+ deps = [
+ ":temp_file",
+ "@abseil-cpp//absl/container:flat_hash_map",
+ "@abseil-cpp//absl/status:statusor",
+ ],
)
cc_library(
@@ -51,6 +56,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 04fc7da61..c7f0e1af2 100644
--- a/tools/common/bazel_substitutions.cc
+++ b/tools/common/bazel_substitutions.cc
@@ -13,47 +13,29 @@
// limitations under the License.
#include "tools/common/bazel_substitutions.h"
+#include "tools/common/process.h"
#include
-#include
#include
-#include