Skip to content

Commit f1e5aef

Browse files
committed
Fix linker filelist parsing when discovering tests
Take the format into account when parsing response files, and consistently track it when we read and write them in various places throughout the build system
1 parent c4d33bf commit f1e5aef

29 files changed

+256
-83
lines changed

Sources/SWBCore/PlannedTaskAction.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ public protocol TaskActionCreationDelegate
349349
func createProcessSDKImportsTaskAction() -> any PlannedTaskAction
350350
func createValidateDependenciesTaskAction() -> any PlannedTaskAction
351351
func createObjectLibraryAssemblerTaskAction() -> any PlannedTaskAction
352-
func createLinkerTaskAction(expandResponseFiles: Bool) -> any PlannedTaskAction
352+
func createLinkerTaskAction(expandResponseFiles: Bool, responseFileFormat: ResponseFileFormat) -> any PlannedTaskAction
353353
}
354354

355355
extension TaskActionCreationDelegate {

Sources/SWBCore/Settings/BuiltinMacros.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,8 @@ public final class BuiltinMacros {
11881188
public static let _WRAPPER_PARENT_PATH = BuiltinMacros.declareStringMacro("_WRAPPER_PARENT_PATH")
11891189
public static let _WRAPPER_RESOURCES_DIR = BuiltinMacros.declareStringMacro("_WRAPPER_RESOURCES_DIR")
11901190
public static let __INPUT_FILE_LIST_PATH__ = BuiltinMacros.declarePathMacro("__INPUT_FILE_LIST_PATH__")
1191-
public static let LINKER_FILE_LIST_FORMAT = BuiltinMacros.declareEnumMacro("LINKER_FILE_LIST_FORMAT") as EnumMacroDeclaration<LinkerFileListFormat>
1191+
public static let LINKER_FILE_LIST_FORMAT = BuiltinMacros.declareEnumMacro("LINKER_FILE_LIST_FORMAT") as EnumMacroDeclaration<ResponseFileFormat>
1192+
public static let LINKER_RESPONSE_FILE_FORMAT = BuiltinMacros.declareEnumMacro("LINKER_RESPONSE_FILE_FORMAT") as EnumMacroDeclaration<ResponseFileFormat>
11921193
public static let SWIFT_RESPONSE_FILE_PATH = BuiltinMacros.declarePathMacro("SWIFT_RESPONSE_FILE_PATH")
11931194
public static let __ARCHS__ = BuiltinMacros.declareStringListMacro("__ARCHS__")
11941195

@@ -2441,6 +2442,7 @@ public final class BuiltinMacros {
24412442
_WRAPPER_RESOURCES_DIR,
24422443
__INPUT_FILE_LIST_PATH__,
24432444
LINKER_FILE_LIST_FORMAT,
2445+
LINKER_RESPONSE_FILE_FORMAT,
24442446
__ARCHS__,
24452447
__SWIFT_MODULE_ONLY_ARCHS__,
24462448
arch,
@@ -2898,12 +2900,8 @@ public enum StripStyle: String, Equatable, Hashable, EnumerationMacroType {
28982900
case debugging
28992901
}
29002902

2901-
public enum LinkerFileListFormat: String, Equatable, Hashable, EnumerationMacroType {
2902-
public static let defaultValue = Self.unescapedNewlineSeparated
2903-
2904-
case unescapedNewlineSeparated
2905-
case unixShellQuotedNewlineSeparated
2906-
case windowsShellQuotedNewlineSeparated
2903+
extension ResponseFileFormat: EnumerationMacroType {
2904+
public static let defaultValue = ResponseFileFormat.unixShellQuotedNewlineSeparated
29072905
}
29082906

29092907
public enum MergedBinaryType: String, Equatable, Hashable, EnumerationMacroType {

Sources/SWBCore/SpecImplementations/LinkerSpec.swift

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -139,20 +139,7 @@ open class LinkerSpec : CommandLineToolSpec, @unchecked Sendable {
139139
}
140140

141141
public func inputFileListContents(_ cbc: CommandBuildContext) -> ByteString {
142-
let contents = OutputByteStream()
143-
for input in cbc.inputs {
144-
switch cbc.scope.evaluate(BuiltinMacros.LINKER_FILE_LIST_FORMAT) {
145-
case .unescapedNewlineSeparated:
146-
contents <<< input.absolutePath.strWithPosixSlashes <<< "\n"
147-
case .unixShellQuotedNewlineSeparated:
148-
let escaper = UNIXShellCommandCodec(encodingStrategy: .singleQuotes, encodingBehavior: .argumentsOnly)
149-
contents <<< escaper.encode([input.absolutePath.strWithPosixSlashes]) <<< "\n"
150-
case .windowsShellQuotedNewlineSeparated:
151-
let escaper = WindowsProcessArgumentsCodec()
152-
contents <<< escaper.encode([input.absolutePath.strWithPosixSlashes]) <<< "\n"
153-
}
154-
}
155-
return contents.bytes
142+
return ByteString(encodingAsUTF8: ResponseFiles.responseFileContents(args: cbc.inputs.map { $0.absolutePath.strWithPosixSlashes }, format: cbc.scope.evaluate(BuiltinMacros.LINKER_FILE_LIST_FORMAT)))
156143
}
157144

158145
open override func constructTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) async {

Sources/SWBCore/SpecImplementations/PropertyDomainSpec.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ private final class EnumBuildOptionType : BuildOptionType {
117117
case "SWIFT_API_DIGESTER_MODE":
118118
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<SwiftAPIDigesterMode>
119119
case "LINKER_FILE_LIST_FORMAT":
120-
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<LinkerFileListFormat>
120+
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<ResponseFileFormat>
121+
case "LINKER_RESPONSE_FILE_FORMAT":
122+
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<ResponseFileFormat>
121123
case "DOCC_MINIMUM_ACCESS_LEVEL":
122124
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<DoccMinimumAccessLevel>
123125
default:

Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ public struct ClangSourceFileIndexingInfo: SourceFileIndexingInfo {
235235
// Skip
236236
} else if arg.starts(with: ByteString(unicodeScalarLiteral: "@")),
237237
let attachmentPath = responseFileMapping[Path(arg.asString.dropFirst())],
238-
let responseFileArgs = try? ResponseFiles.expandResponseFiles(["@\(attachmentPath.str)"], fileSystem: localFS, relativeTo: workingDir) {
238+
let responseFileArgs = try? ResponseFiles.expandResponseFiles(["@\(attachmentPath.str)"], fileSystem: localFS, relativeTo: workingDir, format: .unixShellQuotedSpaceSeparated) {
239239
result.append(contentsOf: responseFileArgs.map { ByteString(encodingAsUTF8: $0) })
240240
} else {
241241
result.append(arg)
@@ -719,7 +719,7 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
719719
ctx.add(string: self.identifier)
720720

721721
let responseFilePath = scope.evaluate(BuiltinMacros.PER_ARCH_OBJECT_FILE_DIR).join("\(ctx.signature.asString)-common-args.resp")
722-
let attachmentPath = producer.writeFileSpec.constructFileTasks(CommandBuildContext(producer: producer, scope: scope, inputs: [], output: responseFilePath), delegate, contents: ByteString(encodingAsUTF8: ResponseFiles.responseFileContents(args: responseFileCommandLine)), permissions: nil, logContents: true, preparesForIndexing: true, additionalTaskOrderingOptions: [.immediate, .ignorePhaseOrdering])
722+
let attachmentPath = producer.writeFileSpec.constructFileTasks(CommandBuildContext(producer: producer, scope: scope, inputs: [], output: responseFilePath), delegate, contents: ByteString(encodingAsUTF8: ResponseFiles.responseFileContents(args: responseFileCommandLine, format: .unixShellQuotedSpaceSeparated)), permissions: nil, logContents: true, preparesForIndexing: true, additionalTaskOrderingOptions: [.immediate, .ignorePhaseOrdering])
723723

724724
return ConstantFlags(flags: regularCommandLine + ["@\(responseFilePath.str)"], headerSearchPaths: headerSearchPaths, inputs: [responseFilePath], responseFileMapping: [responseFilePath: attachmentPath])
725725
} else {

Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,7 +1428,8 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec
14281428

14291429
override public func createTaskAction(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) -> (any PlannedTaskAction)? {
14301430
let useResponseFile = cbc.scope.evaluate(BuiltinMacros.CLANG_USE_RESPONSE_FILE)
1431-
return delegate.taskActionCreationDelegate.createLinkerTaskAction(expandResponseFiles: !useResponseFile)
1431+
let responseFileFormat = cbc.scope.evaluate(BuiltinMacros.LINKER_RESPONSE_FILE_FORMAT)
1432+
return delegate.taskActionCreationDelegate.createLinkerTaskAction(expandResponseFiles: !useResponseFile, responseFileFormat: responseFileFormat)
14321433
}
14331434

14341435
override public func discoveredCommandLineToolSpecInfo(_ producer: any CommandProducer, _ scope: MacroEvaluationScope, _ delegate: any CoreClientTargetDiagnosticProducingDelegate) async -> (any DiscoveredCommandLineToolSpecInfo)? {
@@ -1645,7 +1646,8 @@ public final class LibtoolLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @u
16451646

16461647
override public func createTaskAction(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) -> (any PlannedTaskAction)? {
16471648
let useResponseFile = cbc.scope.evaluate(BuiltinMacros.LIBTOOL_USE_RESPONSE_FILE)
1648-
return delegate.taskActionCreationDelegate.createLinkerTaskAction(expandResponseFiles: !useResponseFile)
1649+
let responseFileFormat = cbc.scope.evaluate(BuiltinMacros.LINKER_RESPONSE_FILE_FORMAT)
1650+
return delegate.taskActionCreationDelegate.createLinkerTaskAction(expandResponseFiles: !useResponseFile, responseFileFormat: responseFileFormat)
16491651
}
16501652

16511653
override public func constructLinkerTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, libraries: [LibrarySpecifier], usedTools: [CommandLineToolSpec: Set<FileTypeSpec>]) async {

Sources/SWBCore/SpecImplementations/Tools/SwiftCompiler.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,9 @@ public struct SwiftDriverPayload: Serializable, TaskPayload, Encodable {
373373
public let linkerResponseFilePath: Path?
374374
public let dependencyFilteringRootPath: Path?
375375
public let verifyScannerDependencies: Bool
376+
public let linkerResponseFileFormat: ResponseFileFormat
376377

377-
internal init(uniqueID: String, compilerLocation: LibSwiftDriver.CompilerLocation, moduleName: String, outputPrefix: String, tempDirPath: Path, explicitModulesTempDirPath: Path, variant: String, architecture: String, eagerCompilationEnabled: Bool, explicitModulesEnabled: Bool, commandLine: [String], ruleInfo: [String], isUsingWholeModuleOptimization: Bool, casOptions: CASOptions?, reportRequiredTargetDependencies: BooleanWarningLevel, linkerResponseFilePath: Path?, dependencyFilteringRootPath: Path?, verifyScannerDependencies: Bool) {
378+
internal init(uniqueID: String, compilerLocation: LibSwiftDriver.CompilerLocation, moduleName: String, outputPrefix: String, tempDirPath: Path, explicitModulesTempDirPath: Path, variant: String, architecture: String, eagerCompilationEnabled: Bool, explicitModulesEnabled: Bool, commandLine: [String], ruleInfo: [String], isUsingWholeModuleOptimization: Bool, casOptions: CASOptions?, reportRequiredTargetDependencies: BooleanWarningLevel, linkerResponseFilePath: Path?, linkerResponseFileFormat: ResponseFileFormat, dependencyFilteringRootPath: Path?, verifyScannerDependencies: Bool) {
378379
self.uniqueID = uniqueID
379380
self.compilerLocation = compilerLocation
380381
self.moduleName = moduleName
@@ -391,12 +392,13 @@ public struct SwiftDriverPayload: Serializable, TaskPayload, Encodable {
391392
self.casOptions = casOptions
392393
self.reportRequiredTargetDependencies = reportRequiredTargetDependencies
393394
self.linkerResponseFilePath = linkerResponseFilePath
395+
self.linkerResponseFileFormat = linkerResponseFileFormat
394396
self.dependencyFilteringRootPath = dependencyFilteringRootPath
395397
self.verifyScannerDependencies = verifyScannerDependencies
396398
}
397399

398400
public init(from deserializer: any Deserializer) throws {
399-
try deserializer.beginAggregate(18)
401+
try deserializer.beginAggregate(19)
400402
self.uniqueID = try deserializer.deserialize()
401403
self.compilerLocation = try deserializer.deserialize()
402404
self.moduleName = try deserializer.deserialize()
@@ -413,12 +415,13 @@ public struct SwiftDriverPayload: Serializable, TaskPayload, Encodable {
413415
self.casOptions = try deserializer.deserialize()
414416
self.reportRequiredTargetDependencies = try deserializer.deserialize()
415417
self.linkerResponseFilePath = try deserializer.deserialize()
418+
self.linkerResponseFileFormat = try deserializer.deserialize()
416419
self.dependencyFilteringRootPath = try deserializer.deserialize()
417420
self.verifyScannerDependencies = try deserializer.deserialize()
418421
}
419422

420423
public func serialize<T>(to serializer: T) where T : Serializer {
421-
serializer.serializeAggregate(18) {
424+
serializer.serializeAggregate(19) {
422425
serializer.serialize(self.uniqueID)
423426
serializer.serialize(self.compilerLocation)
424427
serializer.serialize(self.moduleName)
@@ -435,6 +438,7 @@ public struct SwiftDriverPayload: Serializable, TaskPayload, Encodable {
435438
serializer.serialize(self.casOptions)
436439
serializer.serialize(self.reportRequiredTargetDependencies)
437440
serializer.serialize(self.linkerResponseFilePath)
441+
serializer.serialize(self.linkerResponseFileFormat)
438442
serializer.serialize(self.dependencyFilteringRootPath)
439443
serializer.serialize(self.verifyScannerDependencies)
440444
}
@@ -2560,7 +2564,7 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi
25602564
let explicitModuleBuildEnabled = await swiftExplicitModuleBuildEnabled(cbc.producer, cbc.scope, delegate)
25612565
let verifyScannerDependencies = explicitModuleBuildEnabled && cbc.scope.evaluate(BuiltinMacros.SWIFT_DEPENDENCY_REGISTRATION_MODE) == .verifySwiftDependencyScanner
25622566

2563-
return SwiftDriverPayload(uniqueID: uniqueID, compilerLocation: compilerLocation, moduleName: scope.evaluate(BuiltinMacros.SWIFT_MODULE_NAME), outputPrefix: scope.evaluate(BuiltinMacros.TARGET_NAME) + compilationMode.moduleBaseNameSuffix, tempDirPath: tempDirPath, explicitModulesTempDirPath: explicitModulesTempDirPath, variant: variant, architecture: arch, eagerCompilationEnabled: eagerCompilationEnabled(args: args, scope: scope, compilationMode: compilationMode, isUsingWholeModuleOptimization: isUsingWholeModuleOptimization), explicitModulesEnabled: explicitModuleBuildEnabled, commandLine: commandLine, ruleInfo: ruleInfo, isUsingWholeModuleOptimization: isUsingWholeModuleOptimization, casOptions: casOptions, reportRequiredTargetDependencies: scope.evaluate(BuiltinMacros.DIAGNOSE_MISSING_TARGET_DEPENDENCIES), linkerResponseFilePath: linkerResponseFilePath, dependencyFilteringRootPath: cbc.producer.sdk?.path, verifyScannerDependencies: verifyScannerDependencies)
2567+
return SwiftDriverPayload(uniqueID: uniqueID, compilerLocation: compilerLocation, moduleName: scope.evaluate(BuiltinMacros.SWIFT_MODULE_NAME), outputPrefix: scope.evaluate(BuiltinMacros.TARGET_NAME) + compilationMode.moduleBaseNameSuffix, tempDirPath: tempDirPath, explicitModulesTempDirPath: explicitModulesTempDirPath, variant: variant, architecture: arch, eagerCompilationEnabled: eagerCompilationEnabled(args: args, scope: scope, compilationMode: compilationMode, isUsingWholeModuleOptimization: isUsingWholeModuleOptimization), explicitModulesEnabled: explicitModuleBuildEnabled, commandLine: commandLine, ruleInfo: ruleInfo, isUsingWholeModuleOptimization: isUsingWholeModuleOptimization, casOptions: casOptions, reportRequiredTargetDependencies: scope.evaluate(BuiltinMacros.DIAGNOSE_MISSING_TARGET_DEPENDENCIES), linkerResponseFilePath: linkerResponseFilePath, linkerResponseFileFormat: cbc.scope.evaluate(BuiltinMacros.LINKER_RESPONSE_FILE_FORMAT), dependencyFilteringRootPath: cbc.producer.sdk?.path, verifyScannerDependencies: verifyScannerDependencies)
25642568
}
25652569

25662570
func constructSwiftResponseFileTask(path: Path) {

Sources/SWBGenericUnixPlatform/Specs/UnixLd.xcspec

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,22 @@
186186
Type = Enumeration;
187187
Values = (
188188
unescapedNewlineSeparated,
189+
unixShellQuotedSpaceSeparated,
189190
unixShellQuotedNewlineSeparated,
190191
windowsShellQuotedNewlineSeparated,
191192
);
192193
DefaultValue = unixShellQuotedNewlineSeparated;
194+
},
195+
{
196+
Name = "LINKER_RESPONSE_FILE_FORMAT";
197+
Type = Enumeration;
198+
Values = (
199+
unescapedNewlineSeparated,
200+
unixShellQuotedSpaceSeparated,
201+
unixShellQuotedNewlineSeparated,
202+
windowsShellQuotedNewlineSeparated,
203+
);
204+
DefaultValue = unixShellQuotedSpaceSeparated;
193205
}
194206
);
195207
},

Sources/SWBGenericUnixPlatform/Specs/UnixLibtool.xcspec

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@
7777
windowsShellQuotedNewlineSeparated,
7878
);
7979
DefaultValue = unixShellQuotedNewlineSeparated;
80+
},
81+
{
82+
Name = "LINKER_RESPONSE_FILE_FORMAT";
83+
Type = Enumeration;
84+
Values = (
85+
unescapedNewlineSeparated,
86+
unixShellQuotedSpaceSeparated,
87+
unixShellQuotedNewlineSeparated,
88+
windowsShellQuotedNewlineSeparated,
89+
);
90+
DefaultValue = unixShellQuotedSpaceSeparated;
8091
}
8192
);
8293
},

Sources/SWBTaskExecution/BuildDescriptionManager.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -904,8 +904,8 @@ extension BuildSystemTaskPlanningDelegate: TaskActionCreationDelegate {
904904
return ObjectLibraryAssemblerTaskAction()
905905
}
906906

907-
func createLinkerTaskAction(expandResponseFiles: Bool) -> any PlannedTaskAction {
908-
return LinkerTaskAction(expandResponseFiles: expandResponseFiles)
907+
func createLinkerTaskAction(expandResponseFiles: Bool, responseFileFormat: ResponseFileFormat) -> any PlannedTaskAction {
908+
return LinkerTaskAction(expandResponseFiles: expandResponseFiles, responseFileFormat: responseFileFormat)
909909
}
910910
}
911911

0 commit comments

Comments
 (0)