Skip to content

Commit 6d28b81

Browse files
authored
Fix .swiftsourceinfo readonly bugs in version 3+ (#1550)
Similar to #1533 but when using `--strategy=worker` In rules_swift < 3.x the .swiftsourceinfo files are unconditionally written to the module path. In rules_swift >= 3.x these same files are no longer tracked by Bazel unless explicitly requested. When using non-sandboxed mode, previous builds will contain these files and cause build failures when Swift tries to use them, in order to work around this compatibility issue, we check the module path for the presence of .swiftsourceinfo files and if they are present but not requested, we remove them. Testing: - `bazel clean --expunge` - `git checkout 2.8.2` - `bazel build @com_github_apple_swift_argument_parser//... --strategy=worker,local --worker_sandboxing=false` (pass) - `git checkout master` - `bazel build @com_github_apple_swift_argument_parser//... --strategy=worker,local --worker_sandboxing=false` (failure) - `git checkout <this-branch>` - `bazel build @com_github_apple_swift_argument_parser//... --strategy=worker,local --worker_sandboxing=false` (pass)
1 parent 7445b2c commit 6d28b81

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

tools/worker/swift_runner.cc

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ bool ArgumentEnablesWMO(const std::string &arg) {
2727
arg == "-force-single-frontend-invocation";
2828
}
2929

30+
bool StripPrefix(const std::string &prefix, std::string &str) {
31+
if (str.find(prefix) != 0) {
32+
return false;
33+
}
34+
str.erase(0, prefix.size());
35+
return true;
36+
}
37+
3038
namespace {
3139

3240
// Creates a temporary file and writes the given arguments to it, one per line.
@@ -92,17 +100,6 @@ static std::string Unescape(const std::string &arg) {
92100
return result;
93101
}
94102

95-
// If `str` starts with `prefix`, `str` is mutated to remove `prefix` and the
96-
// function returns true. Otherwise, `str` is left unmodified and the function
97-
// returns `false`.
98-
static bool StripPrefix(const std::string &prefix, std::string &str) {
99-
if (str.find(prefix) != 0) {
100-
return false;
101-
}
102-
str.erase(0, prefix.size());
103-
return true;
104-
}
105-
106103
} // namespace
107104

108105
SwiftRunner::SwiftRunner(const std::vector<std::string> &args,

tools/worker/swift_runner.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
// optimization in the compiler.
3030
extern bool ArgumentEnablesWMO(const std::string &arg);
3131

32+
// If `str` starts with `prefix`, `str` is mutated to remove `prefix` and the
33+
// function returns true. Otherwise, `str` is left unmodified and the function
34+
// returns `false`.
35+
extern bool StripPrefix(const std::string &prefix, std::string &str);
36+
3237
// Handles spawning the Swift compiler driver, making any required substitutions
3338
// of the command line arguments (for example, Bazel's magic Xcode placeholder
3439
// strings).

tools/worker/work_processor.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,19 @@ void WorkProcessor::ProcessWorkRequest(
8686
std::string emit_objc_header_path;
8787
bool is_wmo = false;
8888
bool is_dump_ast = false;
89+
bool emit_swift_source_info = false;
8990

9091
std::string prev_arg;
9192
for (std::string arg : request.arguments) {
9293
std::string original_arg = arg;
9394
// Peel off the `-output-file-map` argument, so we can rewrite it if
9495
// necessary later.
95-
if (arg == "-output-file-map") {
96+
if (StripPrefix("-Xwrapped-swift=", arg)) {
97+
if (arg == "-emit-swiftsourceinfo") {
98+
emit_swift_source_info = true;
99+
}
100+
arg.clear();
101+
} else if (arg == "-output-file-map") {
96102
arg.clear();
97103
} else if (arg == "-dump-ast") {
98104
is_dump_ast = true;
@@ -153,11 +159,23 @@ void WorkProcessor::ProcessWorkRequest(
153159

154160
for (const auto &expected_object_pair :
155161
output_file_map.incremental_inputs()) {
162+
163+
const auto expected_object_path = std::filesystem::path(expected_object_pair.second);
164+
165+
// In rules_swift < 3.x the .swiftsourceinfo files are unconditionally written to the module path.
166+
// In rules_swift >= 3.x these same files are no longer tracked by Bazel unless explicitly requested.
167+
// When using non-sandboxed mode, previous builds will contain these files and cause build failures
168+
// when Swift tries to use them, in order to work around this compatibility issue, we remove them if they are
169+
// present but not requested.
170+
if (expected_object_path.extension() == ".swiftsourceinfo" && !emit_swift_source_info) {
171+
std::filesystem::remove(expected_object_path);
172+
}
173+
156174
// Bazel creates the intermediate directories for the files declared at
157175
// analysis time, but not any any deeper directories, like one can have
158176
// with -emit-objc-header-path, so we need to create those.
159177
const std::string dir_path =
160-
std::filesystem::path(expected_object_pair.second)
178+
expected_object_path
161179
.parent_path()
162180
.string();
163181
dir_paths.insert(dir_path);

0 commit comments

Comments
 (0)