@@ -30,8 +30,6 @@ import ToolchainRegistry
30
30
import XCTest
31
31
#endif
32
32
33
- private struct SwiftSyntaxCShimsModulemapNotFoundError : Error { }
34
-
35
33
package class SwiftPMTestProject : MultiFileTestProject {
36
34
enum Error : Swift . Error {
37
35
/// The `swift` executable could not be found.
@@ -85,9 +83,36 @@ package class SwiftPMTestProject: MultiFileTestProject {
85
83
. first { FileManager . default. fileExists ( at: $0) }
86
84
87
85
guard let swiftSyntaxCShimsModulemap else {
86
+ struct SwiftSyntaxCShimsModulemapNotFoundError : Swift . Error { }
88
87
throw SwiftSyntaxCShimsModulemapNotFoundError ( )
89
88
}
90
89
90
+ // Only link against object files that are listed in the `Objects.LinkFileList`. Otherwise we can get a situation
91
+ // where a `.swift` file is removed from swift-syntax, its `.o` file is still in the build directory because the
92
+ // build folder wasn't cleaned and thus we would link against the stale `.o` file.
93
+ let linkFileListURL =
94
+ productsDirectory
95
+ . appendingPathComponent ( " SourceKitLSPPackageTests.product " )
96
+ . appendingPathComponent ( " Objects.LinkFileList " )
97
+ let linkFileListContents = try ? String ( contentsOf: linkFileListURL, encoding: . utf8)
98
+ guard let linkFileListContents else {
99
+ struct LinkFileListNotFoundError : Swift . Error {
100
+ let url : URL
101
+ }
102
+ throw LinkFileListNotFoundError ( url: linkFileListURL)
103
+ }
104
+ let linkFileList =
105
+ linkFileListContents
106
+ . split ( separator: " \n " )
107
+ . map {
108
+ // Files are wrapped in single quotes if the path contains spaces. Drop the quotes.
109
+ if $0. hasPrefix ( " ' " ) && $0. hasSuffix ( " ' " ) {
110
+ return String ( $0. dropFirst ( ) . dropLast ( ) )
111
+ } else {
112
+ return String ( $0)
113
+ }
114
+ }
115
+
91
116
let swiftSyntaxModulesToLink = [
92
117
" SwiftBasicFormat " ,
93
118
" SwiftCompilerPlugin " ,
@@ -108,7 +133,7 @@ package class SwiftPMTestProject: MultiFileTestProject {
108
133
let dir = productsDirectory. appendingPathComponent ( " \( moduleName) .build " )
109
134
let enumerator = FileManager . default. enumerator ( at: dir, includingPropertiesForKeys: nil )
110
135
while let file = enumerator? . nextObject ( ) as? URL {
111
- if file . pathExtension == " o " {
136
+ if linkFileList . contains ( try file . filePath ) {
112
137
objectFiles. append ( try file. filePath)
113
138
}
114
139
}
0 commit comments