Skip to content

Commit 6e102bb

Browse files
committed
Add swift.use_tmpdir_for_module_cache feature
This adds a new feature, that can be enabled by passing `--features=swift.use_tmpdir_for_module_cache` to the build command. This feature, when enabled, will makes the Swift compilation actions use the shared Clang module cache path written to `/private/tmp/__build_bazel_rules_swift`. This makes the embedded Clang module breadcrumbs deterministic between Bazel instances, because they are always embedded as absolute paths. Note that the use of this cache is non-hermetic--the cached modules are not wiped between builds, and won't be cleaned when invoking `bazel clean`; the user is responsible for manually cleaning them. Additionally, this can be used as a workaround for a bug in the Swift compiler that causes the module breadcrumbs to be embedded even though the `-no-clang-module-breadcrumbs` flag is passed (https://bugs.swift.org/browse/SR-13275).
1 parent bdb2a7b commit 6e102bb

File tree

4 files changed

+120
-1
lines changed

4 files changed

+120
-1
lines changed

swift/internal/compiling.bzl

+24-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ load(
5959
"SWIFT_FEATURE_SYSTEM_MODULE",
6060
"SWIFT_FEATURE_USE_C_MODULES",
6161
"SWIFT_FEATURE_USE_GLOBAL_MODULE_CACHE",
62+
"SWIFT_FEATURE_USE_TMPDIR_FOR_MODULE_CACHE",
6263
"SWIFT_FEATURE_VFSOVERLAY",
6364
)
6465
load(":features.bzl", "are_all_features_enabled", "is_feature_enabled")
@@ -446,7 +447,21 @@ def compile_action_configs():
446447
],
447448
configurators = [_global_module_cache_configurator],
448449
features = [SWIFT_FEATURE_USE_GLOBAL_MODULE_CACHE],
449-
not_features = [SWIFT_FEATURE_USE_C_MODULES],
450+
not_features = [
451+
SWIFT_FEATURE_USE_C_MODULES,
452+
SWIFT_FEATURE_USE_TMPDIR_FOR_MODULE_CACHE,
453+
],
454+
),
455+
swift_toolchain_config.action_config(
456+
actions = [swift_action_names.COMPILE],
457+
configurators = [_use_tmpdir_for_module_cache_configurator],
458+
features = [
459+
SWIFT_FEATURE_USE_TMPDIR_FOR_MODULE_CACHE,
460+
],
461+
not_features = [
462+
SWIFT_FEATURE_USE_C_MODULES,
463+
SWIFT_FEATURE_USE_GLOBAL_MODULE_CACHE,
464+
],
450465
),
451466
swift_toolchain_config.action_config(
452467
actions = [
@@ -461,6 +476,7 @@ def compile_action_configs():
461476
not_features = [
462477
[SWIFT_FEATURE_USE_C_MODULES],
463478
[SWIFT_FEATURE_USE_GLOBAL_MODULE_CACHE],
479+
[SWIFT_FEATURE_USE_TMPDIR_FOR_MODULE_CACHE],
464480
],
465481
),
466482
swift_toolchain_config.action_config(
@@ -818,6 +834,13 @@ def _global_module_cache_configurator(prerequisites, args):
818834
paths.join(prerequisites.bin_dir.path, "_swift_module_cache"),
819835
)
820836

837+
def _use_tmpdir_for_module_cache_configurator(prerequisites, args):
838+
"""Adds flags to use a pre-defined module cache path."""
839+
args.add(
840+
"-module-cache-path",
841+
"/private/tmp/__build_bazel_rules_swift_module_cache",
842+
)
843+
821844
def _batch_mode_configurator(prerequisites, args):
822845
"""Adds flags to enable batch compilation mode."""
823846
if not _is_wmo_manually_requested(prerequisites.user_compile_flags):

swift/internal/feature_names.bzl

+14
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,20 @@ SWIFT_FEATURE_USE_C_MODULES = "swift.use_c_modules"
155155
# crashes.
156156
SWIFT_FEATURE_USE_GLOBAL_MODULE_CACHE = "swift.use_global_module_cache"
157157

158+
# If enabled, Swift compilation actions will use the shared Clang module cache
159+
# path written to `/private/tmp/__build_bazel_rules_swift`. This makes the embedded Clang
160+
# module breadcrumbs deterministic between Bazel instances, because they are
161+
# always embedded as absolute paths. Note that the use of this cache is
162+
# non-hermetic--the cached modules are not wiped between builds, and won't be
163+
# cleaned when invoking `bazel clean`; the user is responsible for manually
164+
# cleaning them.
165+
#
166+
# Additionally, this can be used as a workaround for a bug in the Swift
167+
# compiler that causes the module breadcrumbs to be embedded even though the
168+
# `-no-clang-module-breadcrumbs` flag is passed
169+
# (https://bugs.swift.org/browse/SR-13275).
170+
SWIFT_FEATURE_USE_TMPDIR_FOR_MODULE_CACHE = "swift.use_tmpdir_for_module_cache"
171+
158172
# If enabled, actions invoking the Swift driver or frontend may write argument
159173
# lists into response files (i.e., "@args.txt") to avoid passing command lines
160174
# that exceed the system limit. Toolchains typically set this automatically if

test/BUILD

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
22
load(":debug_settings_tests.bzl", "debug_settings_test_suite")
33
load(":coverage_settings_tests.bzl", "coverage_settings_test_suite")
44
load(":generated_header_tests.bzl", "generated_header_test_suite")
5+
load(":module_cache_settings_tests.bzl", "module_cache_settings_test_suite")
56
load(":private_deps_tests.bzl", "private_deps_test_suite")
67
load(":swift_through_non_swift_tests.bzl", "swift_through_non_swift_test_suite")
78
load(":split_derived_files_tests.bzl", "split_derived_files_test_suite")
@@ -14,6 +15,8 @@ coverage_settings_test_suite()
1415

1516
generated_header_test_suite()
1617

18+
module_cache_settings_test_suite()
19+
1720
private_deps_test_suite()
1821

1922
swift_through_non_swift_test_suite()

test/module_cache_settings_tests.bzl

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Copyright 2020 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Tests for module cache related command line flags under various configs."""
16+
17+
load(
18+
"@build_bazel_rules_swift//test/rules:action_command_line_test.bzl",
19+
"make_action_command_line_test_rule",
20+
)
21+
22+
use_global_module_cache_action_command_line_test = make_action_command_line_test_rule(
23+
config_settings = {
24+
"//command_line_option:features": [
25+
"swift.use_global_module_cache",
26+
],
27+
},
28+
)
29+
30+
use_tmpdir_for_module_cache_action_command_line_test = make_action_command_line_test_rule(
31+
config_settings = {
32+
"//command_line_option:features": [
33+
"swift.use_tmpdir_for_module_cache",
34+
],
35+
},
36+
)
37+
38+
def module_cache_settings_test_suite(name = "module_cache_settings"):
39+
"""Test suite for module cache options.
40+
41+
Args:
42+
name: The name prefix for all the nested tests
43+
"""
44+
45+
# Verify that a global module cache path is passed to swiftc.
46+
use_global_module_cache_action_command_line_test(
47+
name = "{}_global_module_cache_build".format(name),
48+
expected_argv = [
49+
"-module-cache-path",
50+
# Starlark doesn't have support for regular expression yet, so we
51+
# can't verify the whole argument here.
52+
"_swift_module_cache",
53+
],
54+
not_expected_argv = [
55+
],
56+
mnemonic = "SwiftCompile",
57+
tags = [name],
58+
target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple",
59+
)
60+
61+
# Verify that a pre-defined shared module cache path in `/private/tmp` is
62+
# passed to swiftc.
63+
use_tmpdir_for_module_cache_action_command_line_test(
64+
name = "{}_tmpdir_module_cache_build".format(name),
65+
expected_argv = [
66+
"-module-cache-path",
67+
"/private/tmp/__build_bazel_rules_swift_module_cache",
68+
],
69+
not_expected_argv = [
70+
],
71+
mnemonic = "SwiftCompile",
72+
tags = [name],
73+
target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple",
74+
)
75+
76+
native.test_suite(
77+
name = name,
78+
tags = [name],
79+
)

0 commit comments

Comments
 (0)