Skip to content

Commit

Permalink
Feature to opt out of tracking .swiftdoc and .swiftsourceinfo Files (#…
Browse files Browse the repository at this point in the history
…1179)

This PR introduces configuration options aimed at optimizing CI build
processes by excluding non-essential Swift documentation and source info
files, files that don't serve as inputs to other build targets. By
introducing flags to control the exclusion of these files, we aim to
reduce unnecessary network I/O and improve build performance in specific
CI environments. (non-dev facing only)

Features Introduced:

- `swift.emit_swiftdoc`
    - This feature is enabled by default. 
- Opting out of this feature will prevent .swiftdoc files from being
tracked by `SwiftInfo` provider, though they will still be generated by
the Swift compiler.
- These documentation files are generally used for IDE features and are
not required in certain CI contexts, such as non-developer-facing
validation suites.

- `swift.emit_swiftsourceinfo`
  - This feature is enabled by default. 
- When this feature is disabled, .swiftsourceinfo files, which support
source-level debugging, will also be excluded from build outputs and
will not be tracked by `SwiftInfo` provider.

It is important to note that, by default, the Swift compiler generates
.swiftdoc and .swiftsourceinfo files as part of the output when using
the `-emit-module` flag. As of now, this behavior is consistent, given
the absence of compiler options in Swift that permit controlling the
generation of these files.
  • Loading branch information
chiragramani committed Mar 19, 2024
1 parent 380d040 commit a20c388
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 14 deletions.
35 changes: 29 additions & 6 deletions swift/internal/compiling.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ load(
"SWIFT_FEATURE_EMIT_BC",
"SWIFT_FEATURE_EMIT_C_MODULE",
"SWIFT_FEATURE_EMIT_PRIVATE_SWIFTINTERFACE",
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_EMIT_SWIFTINTERFACE",
"SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO",
"SWIFT_FEATURE_EMIT_SYMBOL_GRAPH",
"SWIFT_FEATURE_ENABLE_BATCH_MODE",
"SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION",
Expand Down Expand Up @@ -2372,12 +2374,24 @@ def compile(
swift_toolchain.generated_header_module_implicit_deps_providers.swift_infos
)

# Determine if `.swiftdoc` and `.swiftsourceinfo` files should be included.
include_swiftdoc = is_feature_enabled(
feature_configuration = feature_configuration,
feature_name = SWIFT_FEATURE_EMIT_SWIFTDOC,
)
include_swiftsourceinfo = is_feature_enabled(
feature_configuration = feature_configuration,
feature_name = SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO,
)

compile_outputs, other_outputs = _declare_compile_outputs(
srcs = srcs,
actions = actions,
feature_configuration = feature_configuration,
generated_header_name = generated_header_name,
generated_module_deps_swift_infos = generated_module_deps_swift_infos,
include_swiftdoc = include_swiftdoc,
include_swiftsourceinfo = include_swiftsourceinfo,
module_name = module_name,
target_name = target_name,
user_compile_flags = copts,
Expand All @@ -2401,27 +2415,31 @@ def compile(
# various things (such as the filename prefix for param files generated
# for that action). This guarantees some predictability.
compile_outputs.swiftmodule_file,
compile_outputs.swiftdoc_file,
compile_outputs.swiftsourceinfo_file,
compile_outputs.generated_header_file,
compile_outputs.symbol_graph_directory,
]) + other_outputs
if include_swiftdoc:
all_derived_outputs.append(compile_outputs.swiftdoc_file)
if include_swiftsourceinfo:
all_derived_outputs.append(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.symbol_graph_directory,
]) + compile_outputs.object_files + other_outputs
if include_swiftdoc:
all_compile_outputs.append(compile_outputs.swiftdoc_file)
if include_swiftsourceinfo:
all_compile_outputs.append(compile_outputs.swiftsourceinfo_file)
all_derived_outputs = []

# Merge the providers from our dependencies so that we have one each for
Expand Down Expand Up @@ -2921,6 +2939,8 @@ def _declare_compile_outputs(
feature_configuration,
generated_header_name,
generated_module_deps_swift_infos,
include_swiftdoc,
include_swiftsourceinfo,
module_name,
srcs,
target_name,
Expand All @@ -2936,6 +2956,8 @@ def _declare_compile_outputs(
generated_module_deps_swift_infos: `SwiftInfo` providers from
dependencies of the module for the generated header of the target
being compiled.
include_swiftdoc: If .swiftdoc file should be included or not.
include_swiftsourceinfo: If .swiftsourceinfo file should be included or not.
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
Expand Down Expand Up @@ -2963,11 +2985,12 @@ def _declare_compile_outputs(
swiftdoc_file = derived_files.swiftdoc(
actions = actions,
module_name = module_name,
)
) if include_swiftdoc else None

swiftsourceinfo_file = derived_files.swiftsourceinfo(
actions = actions,
module_name = module_name,
)
) if include_swiftsourceinfo else None

if are_all_features_enabled(
feature_configuration = feature_configuration,
Expand Down
10 changes: 10 additions & 0 deletions swift/internal/feature_names.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,13 @@ SWIFT_FEATURE__SUPPORTS_MACROS = "swift._supports_macros"

# Pass -warnings-as-errors to the compiler.
SWIFT_FEATURE_TREAT_WARNINGS_AS_ERRORS = "swift.treat_warnings_as_errors"

# Defines whether .swiftdoc files are included in build outputs.
# This feature is enabled by default.
# Note: If opted out of this feature, .swiftdoc are generated by the compiler but excluded from Bazel's tracking.
SWIFT_FEATURE_EMIT_SWIFTDOC = "swift.emit_swiftdoc"

# Defines whether .swiftsourceinfo files are included in build outputs.
# This feature is enabled by default.
# Note: If opted out of this feature, .swiftsourceinfo are generated by the compiler but excluded from Bazel's tracking.
SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO = "swift.emit_swiftsourceinfo"
4 changes: 4 additions & 0 deletions swift/internal/swift_autoconfiguration.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ load(
"@build_bazel_rules_swift//swift/internal:feature_names.bzl",
"SWIFT_FEATURE_CODEVIEW_DEBUG_INFO",
"SWIFT_FEATURE_DEBUG_PREFIX_MAP",
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO",
"SWIFT_FEATURE_ENABLE_BATCH_MODE",
"SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES",
"SWIFT_FEATURE_FILE_PREFIX_MAP",
Expand Down Expand Up @@ -365,6 +367,8 @@ def _create_windows_toolchain(repository_ctx):
enabled_features = [
SWIFT_FEATURE_CODEVIEW_DEBUG_INFO,
SWIFT_FEATURE_DEBUG_PREFIX_MAP,
SWIFT_FEATURE_EMIT_SWIFTDOC,
SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO,
SWIFT_FEATURE_ENABLE_BATCH_MODE,
SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES,
SWIFT_FEATURE_SUPPORTS_PRIVATE_DEPS,
Expand Down
4 changes: 4 additions & 0 deletions swift/internal/swift_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ load(
"SWIFT_FEATURE_CACHEABLE_SWIFTMODULES",
"SWIFT_FEATURE_COVERAGE_PREFIX_MAP",
"SWIFT_FEATURE_DEBUG_PREFIX_MAP",
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO",
"SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD",
"SWIFT_FEATURE_NO_GENERATED_MODULE_MAP",
"SWIFT_FEATURE_OPT_USES_WMO",
Expand Down Expand Up @@ -315,6 +317,8 @@ def _swift_toolchain_impl(ctx):
SWIFT_FEATURE_CACHEABLE_SWIFTMODULES,
SWIFT_FEATURE_COVERAGE_PREFIX_MAP,
SWIFT_FEATURE_DEBUG_PREFIX_MAP,
SWIFT_FEATURE_EMIT_SWIFTDOC,
SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO,
SWIFT_FEATURE_NO_GENERATED_MODULE_MAP,
SWIFT_FEATURE_OPT_USES_WMO,
SWIFT_FEATURE_USE_GLOBAL_MODULE_CACHE,
Expand Down
4 changes: 4 additions & 0 deletions swift/internal/xcode_swift_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ load(
"SWIFT_FEATURE_COVERAGE",
"SWIFT_FEATURE_COVERAGE_PREFIX_MAP",
"SWIFT_FEATURE_DEBUG_PREFIX_MAP",
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO",
"SWIFT_FEATURE_ENABLE_BATCH_MODE",
"SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES",
"SWIFT_FEATURE_FILE_PREFIX_MAP",
Expand Down Expand Up @@ -614,6 +616,8 @@ def _xcode_swift_toolchain_impl(ctx):
SWIFT_FEATURE_CACHEABLE_SWIFTMODULES,
SWIFT_FEATURE_COVERAGE_PREFIX_MAP,
SWIFT_FEATURE_DEBUG_PREFIX_MAP,
SWIFT_FEATURE_EMIT_SWIFTDOC,
SWIFT_FEATURE_EMIT_SWIFTSOURCEINFO,
SWIFT_FEATURE_ENABLE_BATCH_MODE,
SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES,
SWIFT_FEATURE_OBJC_LINK_FLAGS,
Expand Down
17 changes: 10 additions & 7 deletions test/rules/provider_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,16 @@ def _compare_expected_files(env, access_description, expected, actual):
"""
actual = _normalize_collection(actual)

expected_is_subset = "*" in expected
expected_include = [
s
for s in expected
if not s.startswith("-") and s != "*"
]

if actual == [None] and not expected_include:
return

if (
not types.is_list(actual) or
any([type(item) != "File" for item in actual])
Expand All @@ -259,13 +269,6 @@ def _compare_expected_files(env, access_description, expected, actual):
return

remaining = list(actual)

expected_is_subset = "*" in expected
expected_include = [
s
for s in expected
if not s.startswith("-") and s != "*"
]
expected_exclude = [s[1:] for s in expected if s.startswith("-")]

# For every expected file, pick off the first actual that we find that has
Expand Down
120 changes: 119 additions & 1 deletion test/split_derived_files_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,36 @@ split_swiftmodule_skip_function_bodies_test = make_action_command_line_test_rule
],
},
)
default_no_split_no_emit_swiftdoc_test = make_provider_test_rule(
config_settings = {
"//command_line_option:features": [
"-swift.emit_swiftdoc",
],
},
)
default_no_split_no_emit_swiftsourceinfo_test = make_provider_test_rule(
config_settings = {
"//command_line_option:features": [
"-swift.emit_swiftsourceinfo",
],
},
)
split_no_emit_swiftdoc_test = make_provider_test_rule(
config_settings = {
"//command_line_option:features": [
"-swift.emit_swiftdoc",
"swift.split_derived_files_generation",
],
},
)
split_no_emit_swiftsourceinfo_test = make_provider_test_rule(
config_settings = {
"//command_line_option:features": [
"-swift.emit_swiftsourceinfo",
"swift.split_derived_files_generation",
],
},
)
split_swiftmodule_indexing_test = make_action_command_line_test_rule(
config_settings = {
"//command_line_option:features": [
Expand Down Expand Up @@ -124,7 +154,7 @@ def split_derived_files_test_suite(name):
)

default_no_split_provider_test(
name = "{}_default_no_split_provider".format(name),
name = "{}_default_no_split_provider_swiftmodule".format(name),
expected_files = [
"test_fixtures_debug_settings_simple.swiftmodule",
],
Expand All @@ -134,6 +164,94 @@ def split_derived_files_test_suite(name):
target_under_test = "@build_bazel_rules_swift//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 = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple",
)

default_no_split_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 = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple",
)

default_no_split_no_emit_swiftdoc_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 = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple",
)

default_no_split_no_emit_swiftsourceinfo_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 = [name],
target_under_test = "@build_bazel_rules_swift//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 = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple",
)

split_swiftmodule_provider_test(
name = "{}_split_provider_swiftsourceinfo".format(name),
field = "direct_modules.swift.swiftsourceinfo",
expected_files = [
"test_fixtures_debug_settings_simple.swiftsourceinfo",
],
provider = "SwiftInfo",
tags = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple",
)

split_no_emit_swiftdoc_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 = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple",
)

split_no_emit_swiftsourceinfo_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 = [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 = [
Expand Down

0 comments on commit a20c388

Please sign in to comment.