diff --git a/swift/internal/actions.bzl b/swift/internal/actions.bzl index 931d22f51..fd7773877 100644 --- a/swift/internal/actions.bzl +++ b/swift/internal/actions.bzl @@ -37,6 +37,10 @@ swift_action_names = struct( # Precompiles an explicit module for a C/Objective-C module map and its # headers, emitting a `.pcm` file. PRECOMPILE_C_MODULE = "SwiftPrecompileCModule", + + # Produces files that are usually fallout of the compilation such as + # .swiftmodule, -Swift.h and more. + DERIVE_FILES = "SwiftDeriveFiles", ) def _apply_configurator(configurator, prerequisites, args): diff --git a/swift/internal/compiling.bzl b/swift/internal/compiling.bzl index a752d4147..778a6ae04 100644 --- a/swift/internal/compiling.bzl +++ b/swift/internal/compiling.bzl @@ -39,6 +39,7 @@ load( "SWIFT_FEATURE_EMIT_SWIFTINTERFACE", "SWIFT_FEATURE_ENABLE_BATCH_MODE", "SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION", + "SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES", "SWIFT_FEATURE_ENABLE_TESTING", "SWIFT_FEATURE_FASTBUILD", "SWIFT_FEATURE_FULL_DEBUG_INFO", @@ -52,6 +53,7 @@ load( "SWIFT_FEATURE_OPT", "SWIFT_FEATURE_OPT_USES_OSIZE", "SWIFT_FEATURE_OPT_USES_WMO", + "SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION", "SWIFT_FEATURE_STRICT_MODULES", "SWIFT_FEATURE_SUPPORTS_LIBRARY_EVOLUTION", "SWIFT_FEATURE_SYSTEM_MODULE", @@ -106,6 +108,10 @@ def compile_action_configs(): actions = [swift_action_names.COMPILE], configurators = [_output_object_or_file_map_configurator], ), + swift_toolchain_config.action_config( + actions = [swift_action_names.DERIVE_FILES], + configurators = [_output_swiftmodule_or_file_map_configurator], + ), # Emit precompiled Clang modules, and embed all files that were read # during compilation into the PCM. @@ -131,11 +137,19 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [swift_action_names.COMPILE], configurators = [_emit_module_path_configurator], + not_features = [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION], + ), + swift_toolchain_config.action_config( + actions = [swift_action_names.DERIVE_FILES], + configurators = [_emit_module_path_configurator], ), # Configure library evolution and the path to the .swiftinterface file. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-enable-library-evolution"), ], @@ -145,23 +159,39 @@ def compile_action_configs(): ], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_emit_module_interface_path_configurator], features = [ SWIFT_FEATURE_SUPPORTS_LIBRARY_EVOLUTION, SWIFT_FEATURE_EMIT_SWIFTINTERFACE, ], ), + + # Configure the path to the emitted *-Swift.h file. swift_toolchain_config.action_config( actions = [swift_action_names.COMPILE], configurators = [_emit_objc_header_path_configurator], + not_features = [ + [SWIFT_FEATURE_NO_GENERATED_HEADER], + [SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION], + ], + ), + swift_toolchain_config.action_config( + actions = [swift_action_names.DERIVE_FILES], + configurators = [_emit_objc_header_path_configurator], not_features = [SWIFT_FEATURE_NO_GENERATED_HEADER], ), # Configure the location where compiler performance statistics are # dumped. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_stats_output_dir_configurator], features = [SWIFT_FEATURE_COMPILE_STATS], ), @@ -177,14 +207,20 @@ def compile_action_configs(): # Define appropriate conditional compilation symbols depending on the # build mode. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-DDEBUG"), ], features = [[SWIFT_FEATURE_DBG], [SWIFT_FEATURE_FASTBUILD]], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-DNDEBUG"), ], @@ -195,14 +231,20 @@ def compile_action_configs(): # `-O` unless the `swift.opt_uses_osize` feature is enabled, then use # `-Osize`. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-Onone"), ], features = [[SWIFT_FEATURE_DBG], [SWIFT_FEATURE_FASTBUILD]], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-O"), ], @@ -210,7 +252,10 @@ def compile_action_configs(): not_features = [SWIFT_FEATURE_OPT_USES_OSIZE], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-Osize"), ], @@ -220,7 +265,10 @@ def compile_action_configs(): # If the `swift.opt_uses_wmo` feature is enabled, opt builds should also # automatically imply whole-module optimization. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-whole-module-optimization"), ], @@ -230,7 +278,10 @@ def compile_action_configs(): # Enable or disable serialization of debugging options into # swiftmodules. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg( "-Xfrontend", @@ -240,7 +291,10 @@ def compile_action_configs(): features = [SWIFT_FEATURE_CACHEABLE_SWIFTMODULES], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg( "-Xfrontend", @@ -255,7 +309,10 @@ def compile_action_configs(): # Enable testability if requested. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-enable-testing"), ], @@ -267,12 +324,18 @@ def compile_action_configs(): # `dsymutil` produces spurious warnings about symbols in the debug map # when run on DI emitted by `-gline-tables-only`. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [swift_toolchain_config.add_arg("-g")], features = [[SWIFT_FEATURE_DBG], [SWIFT_FEATURE_FULL_DEBUG_INFO]], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-gline-tables-only"), ], @@ -282,7 +345,10 @@ def compile_action_configs(): # Make paths written into debug info workspace-relative. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg( "-Xwrapped-swift=-debug-prefix-pwd-is-dot", @@ -297,7 +363,10 @@ def compile_action_configs(): # Make paths written into coverage info workspace-relative. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg( "-Xwrapped-swift=-coverage-prefix-pwd-is-dot", @@ -316,7 +385,10 @@ def compile_action_configs(): # supporting them either. action_configs += [ swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-profile-generate"), swift_toolchain_config.add_arg("-profile-coverage-mapping"), @@ -324,14 +396,20 @@ def compile_action_configs(): features = [SWIFT_FEATURE_COVERAGE], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-sanitize=address"), ], features = ["asan"], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg("-sanitize=thread"), ], @@ -346,6 +424,7 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [ @@ -361,7 +440,10 @@ def compile_action_configs(): # Configure how implicit modules are handled--either using the module # cache, or disabled completely when using explicit modules. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_global_module_cache_configurator], features = [ SWIFT_FEATURE_IMPLICIT_MODULES, @@ -369,7 +451,10 @@ def compile_action_configs(): ], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ swift_toolchain_config.add_arg( "-Xwrapped-swift=-ephemeral-module-cache", @@ -381,6 +466,7 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [ @@ -449,12 +535,18 @@ def compile_action_configs(): #### Search paths for Swift module dependencies action_configs.extend([ swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_dependencies_swiftmodules_configurator], not_features = [SWIFT_FEATURE_VFSOVERLAY], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ _dependencies_swiftmodules_vfsoverlay_configurator, ], @@ -467,6 +559,7 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [_framework_search_paths_configurator], @@ -479,6 +572,7 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [ @@ -492,6 +586,7 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [_dependencies_clang_modules_configurator], @@ -500,6 +595,7 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [_dependencies_clang_modulemaps_configurator], @@ -514,6 +610,7 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [ @@ -532,7 +629,10 @@ def compile_action_configs(): # flags themselves, since some Swift users enable it there as a build # performance hack. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_batch_mode_configurator], features = [SWIFT_FEATURE_ENABLE_BATCH_MODE], not_features = [SWIFT_FEATURE_OPT, SWIFT_FEATURE_OPT_USES_WMO], @@ -540,7 +640,10 @@ def compile_action_configs(): # Set the number of threads to use for WMO. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ partial.make( _wmo_thread_count_configurator, @@ -552,7 +655,10 @@ def compile_action_configs(): features = [SWIFT_FEATURE_OPT, SWIFT_FEATURE_OPT_USES_WMO], ), swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [ partial.make( _wmo_thread_count_configurator, @@ -568,14 +674,29 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [_module_name_configurator], ), + # Pass extra flags for swiftmodule only compilations + swift_toolchain_config.action_config( + actions = [swift_action_names.DERIVE_FILES], + configurators = [ + swift_toolchain_config.add_arg( + "-experimental-skip-non-inlinable-function-bodies", + ), + ], + features = [SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES], + ), + # Configure index-while-building. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_index_while_building_configurator], features = [SWIFT_FEATURE_INDEX_WHILE_BUILDING], ), @@ -583,13 +704,19 @@ def compile_action_configs(): # User-defined conditional compilation flags (defined for Swift; those # passed directly to ClangImporter are handled above). swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_conditional_compilation_flag_configurator], ), # Disable auto-linking for prebuilt static frameworks. swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_static_frameworks_disable_autolink_configurator], ), ] @@ -600,7 +727,10 @@ def compile_action_configs(): # the rule implementations as a last resort. action_configs.append( swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_user_compile_flags_configurator], ), ) @@ -609,6 +739,7 @@ def compile_action_configs(): swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [_source_files_configurator], @@ -618,33 +749,50 @@ def compile_action_configs(): # Add additional input files to the sandbox (does not modify flags). action_configs.append( swift_toolchain_config.action_config( - actions = [swift_action_names.COMPILE], + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], configurators = [_additional_inputs_configurator], ), ) return action_configs -def _output_object_or_file_map_configurator(prerequisites, args): - """Adds the output file map or single object file to the command line.""" - output_file_map = prerequisites.output_file_map +def _output_or_file_map(output_file_map, outputs, args): + """Adds the output file map or single file to the command line.""" if output_file_map: args.add("-output-file-map", output_file_map) return swift_toolchain_config.config_result( inputs = [output_file_map], ) - object_files = prerequisites.object_files - if len(object_files) != 1: + if len(outputs) != 1: fail( "Internal error: If not using an output file map, there should " + "only be a single object file expected as the output, but we " + - "found: {}".format(object_files), + "found: {}".format(outputs), ) - args.add("-o", object_files[0]) + args.add("-o", outputs[0]) return None +def _output_object_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.output_file_map, + outputs = prerequisites.object_files, + 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.output_file_map, + outputs = [prerequisites.swiftmodule_file], + args = args, + ) + def _output_pcm_file_configurator(prerequisites, args): """Adds the `.pcm` output path to the command line.""" args.add("-o", prerequisites.pcm_file) @@ -1175,18 +1323,41 @@ def compile( target_name = target_name, user_compile_flags = copts + swift_toolchain.command_line_copts, ) - 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.generated_header_file, - compile_outputs.indexstore_directory, - compile_outputs.stats_directory, - ]) + compile_outputs.object_files + other_outputs + + split_derived_file_generation = is_feature_enabled( + feature_configuration = feature_configuration, + feature_name = SWIFT_FEATURE_SPLIT_DERIVED_FILES_GENERATION, + ) + + if split_derived_file_generation: + all_compile_outputs = compact([ + compile_outputs.swiftinterface_file, + compile_outputs.indexstore_directory, + compile_outputs.stats_directory, + ]) + compile_outputs.object_files + all_derived_outputs = compact([ + # The `.swiftmodule` file is explicitly listed as the first output + # because it will always exist and because Bazel uses it as a key for + # various things (such as the filename prefix for param files generated + # for that action). This guarantees some predictability. + compile_outputs.swiftmodule_file, + compile_outputs.swiftdoc_file, + compile_outputs.generated_header_file, + ]) + other_outputs + 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.generated_header_file, + compile_outputs.indexstore_directory, + compile_outputs.stats_directory, + ]) + compile_outputs.object_files + other_outputs + all_derived_outputs = [] # Merge the providers from our dependencies so that we have one each for # `SwiftInfo`, `CcInfo`, and `apple_common.Objc`. Then we can pass these @@ -1260,6 +1431,19 @@ def compile( **struct_fields(compile_outputs) ) + if split_derived_file_generation: + run_toolchain_action( + actions = actions, + action_name = swift_action_names.DERIVE_FILES, + feature_configuration = feature_configuration, + outputs = all_derived_outputs, + prerequisites = prerequisites, + progress_message = ( + "Generating derived files for Swift module {}".format(module_name) + ), + swift_toolchain = swift_toolchain, + ) + run_toolchain_action( actions = actions, action_name = swift_action_names.COMPILE, diff --git a/swift/internal/feature_names.bzl b/swift/internal/feature_names.bzl index ad3ed8969..21257554a 100644 --- a/swift/internal/feature_names.bzl +++ b/swift/internal/feature_names.bzl @@ -227,3 +227,12 @@ SWIFT_FEATURE_NO_EMBED_DEBUG_MODULE = "swift.no_embed_debug_module" # files where the protoc command line might not be crafted correctly, so it # remains opt in. SWIFT_FEATURE_GENERATE_FROM_RAW_PROTO_FILES = "swift.generate_from_raw_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" diff --git a/swift/internal/swift_autoconfiguration.bzl b/swift/internal/swift_autoconfiguration.bzl index 48b772acf..dbcf1af9b 100644 --- a/swift/internal/swift_autoconfiguration.bzl +++ b/swift/internal/swift_autoconfiguration.bzl @@ -28,6 +28,7 @@ load( "@build_bazel_rules_swift//swift/internal:feature_names.bzl", "SWIFT_FEATURE_DEBUG_PREFIX_MAP", "SWIFT_FEATURE_ENABLE_BATCH_MODE", + "SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES", "SWIFT_FEATURE_IMPLICIT_MODULES", "SWIFT_FEATURE_MODULE_MAP_NO_PRIVATE_HEADERS", "SWIFT_FEATURE_SUPPORTS_PRIVATE_DEPS", @@ -75,6 +76,15 @@ def _check_enable_batch_mode(repository_ctx, swiftc_path, temp_dir): "-enable-batch-mode", ) +def _check_skip_function_bodies(repository_ctx, swiftc_path, temp_dir): + """Returns True if `swiftc` supports skip function bodies.""" + return _swift_succeeds( + repository_ctx, + swiftc_path, + "-version", + "-experimental-skip-non-inlinable-function-bodies", + ) + def _check_debug_prefix_map(repository_ctx, swiftc_path, temp_dir): """Returns True if `swiftc` supports debug prefix mapping.""" return _swift_succeeds( @@ -187,6 +197,7 @@ def _compute_feature_values(repository_ctx, swiftc_path): _FEATURE_CHECKS = { SWIFT_FEATURE_DEBUG_PREFIX_MAP: _check_debug_prefix_map, SWIFT_FEATURE_ENABLE_BATCH_MODE: _check_enable_batch_mode, + SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES: _check_skip_function_bodies, SWIFT_FEATURE_SUPPORTS_PRIVATE_DEPS: _check_supports_private_deps, SWIFT_FEATURE_USE_RESPONSE_FILES: _check_use_response_files, } diff --git a/swift/internal/swift_toolchain.bzl b/swift/internal/swift_toolchain.bzl index 40e0ee879..c975787bc 100644 --- a/swift/internal/swift_toolchain.bzl +++ b/swift/internal/swift_toolchain.bzl @@ -59,6 +59,15 @@ def _all_tool_configs( """ _swift_driver_tool_config = swift_toolchain_config.driver_tool_config + compile_tool_config = _swift_driver_tool_config( + driver_mode = "swiftc", + swift_executable = swift_executable, + toolchain_root = toolchain_root, + use_param_file = use_param_file, + worker_mode = "persistent", + additional_tools = additional_tools, + ) + return { swift_action_names.AUTOLINK_EXTRACT: _swift_driver_tool_config( driver_mode = "swift-autolink-extract", @@ -67,14 +76,8 @@ def _all_tool_configs( worker_mode = "wrap", additional_tools = additional_tools, ), - swift_action_names.COMPILE: _swift_driver_tool_config( - driver_mode = "swiftc", - swift_executable = swift_executable, - toolchain_root = toolchain_root, - use_param_file = use_param_file, - worker_mode = "persistent", - additional_tools = additional_tools, - ), + swift_action_names.COMPILE: compile_tool_config, + swift_action_names.DERIVE_FILES: compile_tool_config, swift_action_names.MODULEWRAP: _swift_driver_tool_config( # This must come first after the driver name. args = ["-modulewrap"], diff --git a/swift/internal/xcode_swift_toolchain.bzl b/swift/internal/xcode_swift_toolchain.bzl index 4e0209835..5a0d2a6cf 100644 --- a/swift/internal/xcode_swift_toolchain.bzl +++ b/swift/internal/xcode_swift_toolchain.bzl @@ -34,6 +34,7 @@ load( "SWIFT_FEATURE_BUNDLED_XCTESTS", "SWIFT_FEATURE_DEBUG_PREFIX_MAP", "SWIFT_FEATURE_ENABLE_BATCH_MODE", + "SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES", "SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD", "SWIFT_FEATURE_MODULE_MAP_NO_PRIVATE_HEADERS", "SWIFT_FEATURE_SUPPORTS_LIBRARY_EVOLUTION", @@ -287,6 +288,7 @@ def _all_action_configs( swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [ @@ -317,6 +319,7 @@ def _all_action_configs( swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [swift_toolchain_config.add_arg("-embed-bitcode")], @@ -325,6 +328,7 @@ def _all_action_configs( swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [ @@ -342,6 +346,7 @@ def _all_action_configs( swift_toolchain_config.action_config( actions = [ swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, swift_action_names.PRECOMPILE_C_MODULE, ], configurators = [ @@ -389,16 +394,19 @@ def _all_tool_configs( env = dict(env) env["TOOLCHAINS"] = custom_toolchain + tool_config = swift_toolchain_config.driver_tool_config( + driver_mode = "swiftc", + env = env, + execution_requirements = execution_requirements, + swift_executable = swift_executable, + toolchain_root = toolchain_root, + use_param_file = use_param_file, + worker_mode = "persistent", + ) + tool_configs = { - swift_action_names.COMPILE: swift_toolchain_config.driver_tool_config( - driver_mode = "swiftc", - env = env, - execution_requirements = execution_requirements, - swift_executable = swift_executable, - toolchain_root = toolchain_root, - use_param_file = use_param_file, - worker_mode = "persistent", - ), + swift_action_names.COMPILE: tool_config, + swift_action_names.DERIVE_FILES: tool_config, } # Xcode 12.0 implies Swift 5.3. @@ -594,6 +602,10 @@ def _xcode_swift_toolchain_impl(ctx): requested_features.append(SWIFT_FEATURE_SUPPORTS_LIBRARY_EVOLUTION) requested_features.append(SWIFT_FEATURE_SUPPORTS_PRIVATE_DEPS) + # Xcode 11.4 implies Swift 5.2. + if _is_xcode_at_least_version(xcode_config, "11.4"): + requested_features.append(SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES) + command_line_copts = _command_line_objc_copts( ctx.var["COMPILATION_MODE"], ctx.fragments.objc, diff --git a/test/BUILD b/test/BUILD index ea685d048..70dcb37e7 100644 --- a/test/BUILD +++ b/test/BUILD @@ -4,6 +4,7 @@ load(":coverage_settings_tests.bzl", "coverage_settings_test_suite") load(":generated_header_tests.bzl", "generated_header_test_suite") load(":private_deps_tests.bzl", "private_deps_test_suite") load(":swift_through_non_swift_tests.bzl", "swift_through_non_swift_test_suite") +load(":split_derived_files_tests.bzl", "split_derived_files_test_suite") licenses(["notice"]) @@ -17,6 +18,8 @@ private_deps_test_suite() swift_through_non_swift_test_suite() +split_derived_files_test_suite() + test_suite( name = "all_tests", ) diff --git a/test/split_derived_files_tests.bzl b/test/split_derived_files_tests.bzl new file mode 100644 index 000000000..89baa9b47 --- /dev/null +++ b/test/split_derived_files_tests.bzl @@ -0,0 +1,226 @@ +"""Tests for derived files related command line flags under various configs.""" + +load( + "@build_bazel_rules_swift//test/rules:action_command_line_test.bzl", + "make_action_command_line_test_rule", +) +load( + "@build_bazel_rules_swift//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() +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_wmo_test = make_action_command_line_test_rule( + config_settings = { + "//command_line_option:swiftcopt": [ + "-whole-module-optimization", + ], + "//command_line_option:features": [ + "swift.split_derived_files_generation", + ], + }, +) +split_swiftmodule_wmo_provider_test = make_provider_test_rule( + config_settings = { + "//command_line_option:swiftcopt": [ + "-whole-module-optimization", + ], + "//command_line_option:features": [ + "swift.split_derived_files_generation", + ], + }, +) +split_swiftmodule_skip_function_bodies_test = make_action_command_line_test_rule( + config_settings = { + "//command_line_option:swiftcopt": [ + "-whole-module-optimization", + ], + "//command_line_option:features": [ + "swift.split_derived_files_generation", + "swift.enable_skip_function_bodies", + ], + }, +) + +def split_derived_files_test_suite(name = "split_derived_files"): + """Test suite for split derived files options. + + Args: + name: The name prefix for all the nested tests + """ + default_no_split_test( + name = "{}_default_no_split_args".format(name), + expected_argv = [ + "-emit-module-path", + "-emit-object", + ], + mnemonic = "SwiftCompile", + tags = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", + ) + + default_no_split_provider_test( + name = "{}_default_no_split_provider".format(name), + expected_files = [ + "test_fixtures_debug_settings_simple.swiftmodule", + ], + field = "direct_modules.swift.swiftmodule", + provider = "SwiftInfo", + tags = [name], + target_under_test = "@build_bazel_rules_swift//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.libraries_to_link.pic_static_library!", + provider = "CcInfo", + tags = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", + ) + + split_swiftmodule_test( + name = "{}_object_only".format(name), + expected_argv = [ + "-emit-object", + ], + mnemonic = "SwiftCompile", + not_expected_argv = [ + "-emit-module-path", + ], + tags = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", + ) + + split_swiftmodule_test( + name = "{}_swiftmodule_only".format(name), + expected_argv = [ + "-emit-module-path", + ], + mnemonic = "SwiftDeriveFiles", + not_expected_argv = [ + "-emit-object", + ], + tags = [name], + target_under_test = "@build_bazel_rules_swift//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 = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", + ) + + split_swiftmodule_provider_test( + name = "{}_split_provider_ccinfo".format(name), + expected_files = [ + "libsimple.a", + ], + field = "linking_context.libraries_to_link.pic_static_library!", + provider = "CcInfo", + tags = [name], + target_under_test = "@build_bazel_rules_swift//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 = [name], + target_under_test = "@build_bazel_rules_swift//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 = [name], + target_under_test = "@build_bazel_rules_swift//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 = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", + ) + + split_swiftmodule_wmo_provider_test( + name = "{}_split_wmo_provider_ccinfo".format(name), + expected_files = [ + "libsimple.a", + ], + field = "linking_context.libraries_to_link.pic_static_library!", + provider = "CcInfo", + tags = [name], + target_under_test = "@build_bazel_rules_swift//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 = [name], + target_under_test = "@build_bazel_rules_swift//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 = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", + ) + + native.test_suite( + name = name, + tags = [name], + )