Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/SWBCore/PlannedTaskAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ public protocol TaskActionCreationDelegate
func createProcessSDKImportsTaskAction() -> any PlannedTaskAction
func createValidateDependenciesTaskAction() -> any PlannedTaskAction
func createObjectLibraryAssemblerTaskAction() -> any PlannedTaskAction
func createLinkerTaskAction(expandResponseFiles: Bool) -> any PlannedTaskAction
func createLinkerTaskAction(expandResponseFiles: Bool, responseFileFormat: ResponseFileFormat) -> any PlannedTaskAction
}

extension TaskActionCreationDelegate {
Expand Down
12 changes: 5 additions & 7 deletions Sources/SWBCore/Settings/BuiltinMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,8 @@ public final class BuiltinMacros {
public static let _WRAPPER_PARENT_PATH = BuiltinMacros.declareStringMacro("_WRAPPER_PARENT_PATH")
public static let _WRAPPER_RESOURCES_DIR = BuiltinMacros.declareStringMacro("_WRAPPER_RESOURCES_DIR")
public static let __INPUT_FILE_LIST_PATH__ = BuiltinMacros.declarePathMacro("__INPUT_FILE_LIST_PATH__")
public static let LINKER_FILE_LIST_FORMAT = BuiltinMacros.declareEnumMacro("LINKER_FILE_LIST_FORMAT") as EnumMacroDeclaration<LinkerFileListFormat>
public static let LINKER_FILE_LIST_FORMAT = BuiltinMacros.declareEnumMacro("LINKER_FILE_LIST_FORMAT") as EnumMacroDeclaration<ResponseFileFormat>
public static let LINKER_RESPONSE_FILE_FORMAT = BuiltinMacros.declareEnumMacro("LINKER_RESPONSE_FILE_FORMAT") as EnumMacroDeclaration<ResponseFileFormat>
public static let SWIFT_RESPONSE_FILE_PATH = BuiltinMacros.declarePathMacro("SWIFT_RESPONSE_FILE_PATH")
public static let __ARCHS__ = BuiltinMacros.declareStringListMacro("__ARCHS__")

Expand Down Expand Up @@ -2441,6 +2442,7 @@ public final class BuiltinMacros {
_WRAPPER_RESOURCES_DIR,
__INPUT_FILE_LIST_PATH__,
LINKER_FILE_LIST_FORMAT,
LINKER_RESPONSE_FILE_FORMAT,
__ARCHS__,
__SWIFT_MODULE_ONLY_ARCHS__,
arch,
Expand Down Expand Up @@ -2898,12 +2900,8 @@ public enum StripStyle: String, Equatable, Hashable, EnumerationMacroType {
case debugging
}

public enum LinkerFileListFormat: String, Equatable, Hashable, EnumerationMacroType {
public static let defaultValue = Self.unescapedNewlineSeparated

case unescapedNewlineSeparated
case unixShellQuotedNewlineSeparated
case windowsShellQuotedNewlineSeparated
extension ResponseFileFormat: EnumerationMacroType {
public static let defaultValue = ResponseFileFormat.unixShellQuotedNewlineSeparated
}

public enum MergedBinaryType: String, Equatable, Hashable, EnumerationMacroType {
Expand Down
15 changes: 1 addition & 14 deletions Sources/SWBCore/SpecImplementations/LinkerSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,7 @@ open class LinkerSpec : CommandLineToolSpec, @unchecked Sendable {
}

public func inputFileListContents(_ cbc: CommandBuildContext) -> ByteString {
let contents = OutputByteStream()
for input in cbc.inputs {
switch cbc.scope.evaluate(BuiltinMacros.LINKER_FILE_LIST_FORMAT) {
case .unescapedNewlineSeparated:
contents <<< input.absolutePath.strWithPosixSlashes <<< "\n"
case .unixShellQuotedNewlineSeparated:
let escaper = UNIXShellCommandCodec(encodingStrategy: .singleQuotes, encodingBehavior: .argumentsOnly)
contents <<< escaper.encode([input.absolutePath.strWithPosixSlashes]) <<< "\n"
case .windowsShellQuotedNewlineSeparated:
let escaper = WindowsProcessArgumentsCodec()
contents <<< escaper.encode([input.absolutePath.strWithPosixSlashes]) <<< "\n"
}
}
return contents.bytes
return ByteString(encodingAsUTF8: ResponseFiles.responseFileContents(args: cbc.inputs.map { $0.absolutePath.strWithPosixSlashes }, format: cbc.scope.evaluate(BuiltinMacros.LINKER_FILE_LIST_FORMAT)))
}

open override func constructTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ private final class EnumBuildOptionType : BuildOptionType {
case "SWIFT_API_DIGESTER_MODE":
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<SwiftAPIDigesterMode>
case "LINKER_FILE_LIST_FORMAT":
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<LinkerFileListFormat>
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<ResponseFileFormat>
case "LINKER_RESPONSE_FILE_FORMAT":
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<ResponseFileFormat>
case "DOCC_MINIMUM_ACCESS_LEVEL":
return try namespace.declareEnumMacro(name) as EnumMacroDeclaration<DoccMinimumAccessLevel>
default:
Expand Down
4 changes: 2 additions & 2 deletions Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public struct ClangSourceFileIndexingInfo: SourceFileIndexingInfo {
// Skip
} else if arg.starts(with: ByteString(unicodeScalarLiteral: "@")),
let attachmentPath = responseFileMapping[Path(arg.asString.dropFirst())],
let responseFileArgs = try? ResponseFiles.expandResponseFiles(["@\(attachmentPath.str)"], fileSystem: localFS, relativeTo: workingDir) {
let responseFileArgs = try? ResponseFiles.expandResponseFiles(["@\(attachmentPath.str)"], fileSystem: localFS, relativeTo: workingDir, format: .unixShellQuotedSpaceSeparated) {
result.append(contentsOf: responseFileArgs.map { ByteString(encodingAsUTF8: $0) })
} else {
result.append(arg)
Expand Down Expand Up @@ -719,7 +719,7 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
ctx.add(string: self.identifier)

let responseFilePath = scope.evaluate(BuiltinMacros.PER_ARCH_OBJECT_FILE_DIR).join("\(ctx.signature.asString)-common-args.resp")
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])
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])

return ConstantFlags(flags: regularCommandLine + ["@\(responseFilePath.str)"], headerSearchPaths: headerSearchPaths, inputs: [responseFilePath], responseFileMapping: [responseFilePath: attachmentPath])
} else {
Expand Down
6 changes: 4 additions & 2 deletions Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,8 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec

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

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

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

override public func constructLinkerTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, libraries: [LibrarySpecifier], usedTools: [CommandLineToolSpec: Set<FileTypeSpec>]) async {
Expand Down
12 changes: 8 additions & 4 deletions Sources/SWBCore/SpecImplementations/Tools/SwiftCompiler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,9 @@ public struct SwiftDriverPayload: Serializable, TaskPayload, Encodable {
public let linkerResponseFilePath: Path?
public let dependencyFilteringRootPath: Path?
public let verifyScannerDependencies: Bool
public let linkerResponseFileFormat: ResponseFileFormat

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) {
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) {
self.uniqueID = uniqueID
self.compilerLocation = compilerLocation
self.moduleName = moduleName
Expand All @@ -391,12 +392,13 @@ public struct SwiftDriverPayload: Serializable, TaskPayload, Encodable {
self.casOptions = casOptions
self.reportRequiredTargetDependencies = reportRequiredTargetDependencies
self.linkerResponseFilePath = linkerResponseFilePath
self.linkerResponseFileFormat = linkerResponseFileFormat
self.dependencyFilteringRootPath = dependencyFilteringRootPath
self.verifyScannerDependencies = verifyScannerDependencies
}

public init(from deserializer: any Deserializer) throws {
try deserializer.beginAggregate(18)
try deserializer.beginAggregate(19)
self.uniqueID = try deserializer.deserialize()
self.compilerLocation = try deserializer.deserialize()
self.moduleName = try deserializer.deserialize()
Expand All @@ -413,12 +415,13 @@ public struct SwiftDriverPayload: Serializable, TaskPayload, Encodable {
self.casOptions = try deserializer.deserialize()
self.reportRequiredTargetDependencies = try deserializer.deserialize()
self.linkerResponseFilePath = try deserializer.deserialize()
self.linkerResponseFileFormat = try deserializer.deserialize()
self.dependencyFilteringRootPath = try deserializer.deserialize()
self.verifyScannerDependencies = try deserializer.deserialize()
}

public func serialize<T>(to serializer: T) where T : Serializer {
serializer.serializeAggregate(18) {
serializer.serializeAggregate(19) {
serializer.serialize(self.uniqueID)
serializer.serialize(self.compilerLocation)
serializer.serialize(self.moduleName)
Expand All @@ -435,6 +438,7 @@ public struct SwiftDriverPayload: Serializable, TaskPayload, Encodable {
serializer.serialize(self.casOptions)
serializer.serialize(self.reportRequiredTargetDependencies)
serializer.serialize(self.linkerResponseFilePath)
serializer.serialize(self.linkerResponseFileFormat)
serializer.serialize(self.dependencyFilteringRootPath)
serializer.serialize(self.verifyScannerDependencies)
}
Expand Down Expand Up @@ -2560,7 +2564,7 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi
let explicitModuleBuildEnabled = await swiftExplicitModuleBuildEnabled(cbc.producer, cbc.scope, delegate)
let verifyScannerDependencies = explicitModuleBuildEnabled && cbc.scope.evaluate(BuiltinMacros.SWIFT_DEPENDENCY_REGISTRATION_MODE) == .verifySwiftDependencyScanner

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)
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)
}

func constructSwiftResponseFileTask(path: Path) {
Expand Down
12 changes: 12 additions & 0 deletions Sources/SWBGenericUnixPlatform/Specs/UnixLd.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,22 @@
Type = Enumeration;
Values = (
unescapedNewlineSeparated,
unixShellQuotedSpaceSeparated,
unixShellQuotedNewlineSeparated,
windowsShellQuotedNewlineSeparated,
);
DefaultValue = unixShellQuotedNewlineSeparated;
},
{
Name = "LINKER_RESPONSE_FILE_FORMAT";
Type = Enumeration;
Values = (
unescapedNewlineSeparated,
unixShellQuotedSpaceSeparated,
unixShellQuotedNewlineSeparated,
windowsShellQuotedNewlineSeparated,
);
DefaultValue = unixShellQuotedSpaceSeparated;
}
);
},
Expand Down
11 changes: 11 additions & 0 deletions Sources/SWBGenericUnixPlatform/Specs/UnixLibtool.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@
windowsShellQuotedNewlineSeparated,
);
DefaultValue = unixShellQuotedNewlineSeparated;
},
{
Name = "LINKER_RESPONSE_FILE_FORMAT";
Type = Enumeration;
Values = (
unescapedNewlineSeparated,
unixShellQuotedSpaceSeparated,
unixShellQuotedNewlineSeparated,
windowsShellQuotedNewlineSeparated,
);
DefaultValue = unixShellQuotedSpaceSeparated;
}
);
},
Expand Down
4 changes: 2 additions & 2 deletions Sources/SWBTaskExecution/BuildDescriptionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -904,8 +904,8 @@ extension BuildSystemTaskPlanningDelegate: TaskActionCreationDelegate {
return ObjectLibraryAssemblerTaskAction()
}

func createLinkerTaskAction(expandResponseFiles: Bool) -> any PlannedTaskAction {
return LinkerTaskAction(expandResponseFiles: expandResponseFiles)
func createLinkerTaskAction(expandResponseFiles: Bool, responseFileFormat: ResponseFileFormat) -> any PlannedTaskAction {
return LinkerTaskAction(expandResponseFiles: expandResponseFiles, responseFileFormat: responseFileFormat)
}
}

Expand Down
1 change: 1 addition & 0 deletions Sources/SWBTaskExecution/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ add_library(SWBTaskExecution
DynamicTaskSpecs/SwiftDriverJobDynamicTaskSpec.swift
DynamicTaskSpecs/SwiftDriverPlanningDynamicTaskSpec.swift
ProjectPlanner.swift
ResponseFileFormat+ExpressibleByArgument.swift
Task.swift
TaskActionExtensionPoint.swift
TaskActions/AuxiliaryFileTaskAction.swift
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

public import ArgumentParser
import SWBUtil

extension ResponseFileFormat: ExpressibleByArgument {}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public final class ClangScanTaskAction: TaskAction, BuildValueValidatingTaskActi
self.scanningOutput = parsedOutput
if expandResponseFiles {
do {
self.commandLine = try ResponseFiles.expandResponseFiles(cliArguments, fileSystem: executionDelegate.fs, relativeTo: workingDirectory)
self.commandLine = try ResponseFiles.expandResponseFiles(cliArguments, fileSystem: executionDelegate.fs, relativeTo: workingDirectory, format: .unixShellQuotedSpaceSeparated)
} catch {
outputDelegate.error(error.localizedDescription)
return nil
Expand Down
15 changes: 10 additions & 5 deletions Sources/SWBTaskExecution/TaskActions/LinkerTaskAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,26 @@ public final class LinkerTaskAction: TaskAction {

/// Whether response files should be expanded before invoking the linker.
private let expandResponseFiles: Bool

public init(expandResponseFiles: Bool) {
private let responseFileFormat: ResponseFileFormat

public init(expandResponseFiles: Bool, responseFileFormat: ResponseFileFormat) {
self.expandResponseFiles = expandResponseFiles
self.responseFileFormat = responseFileFormat
super.init()
}

public override func serialize<T: Serializer>(to serializer: T) {
serializer.beginAggregate(2)
serializer.beginAggregate(3)
serializer.serialize(expandResponseFiles)
serializer.serialize(responseFileFormat)
super.serialize(to: serializer)
serializer.endAggregate()
}

public required init(from deserializer: any Deserializer) throws {
try deserializer.beginAggregate(2)
try deserializer.beginAggregate(3)
self.expandResponseFiles = try deserializer.deserialize()
self.responseFileFormat = try deserializer.deserialize()
try super.init(from: deserializer)
}

Expand All @@ -55,7 +59,8 @@ public final class LinkerTaskAction: TaskAction {
commandLine = try ResponseFiles.expandResponseFiles(
commandLine,
fileSystem: executionDelegate.fs,
relativeTo: task.workingDirectory
relativeTo: task.workingDirectory,
format: responseFileFormat
)
} catch {
outputDelegate.emitError("Failed to expand response files: \(error.localizedDescription)")
Expand Down
Loading
Loading