Skip to content

Commit 5e80741

Browse files
committed
Take the host platform into account when writing clang response files
1 parent d254698 commit 5e80741

File tree

5 files changed

+47
-22
lines changed

5 files changed

+47
-22
lines changed

Sources/SWBCore/Settings/BuiltinMacros.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,7 @@ public final class BuiltinMacros {
11891189
public static let _WRAPPER_PARENT_PATH = BuiltinMacros.declareStringMacro("_WRAPPER_PARENT_PATH")
11901190
public static let _WRAPPER_RESOURCES_DIR = BuiltinMacros.declareStringMacro("_WRAPPER_RESOURCES_DIR")
11911191
public static let __INPUT_FILE_LIST_PATH__ = BuiltinMacros.declarePathMacro("__INPUT_FILE_LIST_PATH__")
1192+
public static let HOST_RESPONSE_FILE_FORMAT = BuiltinMacros.declareEnumMacro("HOST_RESPONSE_FILE_FORMAT") as EnumMacroDeclaration<ResponseFileFormat>
11921193
public static let LINKER_FILE_LIST_FORMAT = BuiltinMacros.declareEnumMacro("LINKER_FILE_LIST_FORMAT") as EnumMacroDeclaration<ResponseFileFormat>
11931194
public static let LINKER_RESPONSE_FILE_FORMAT = BuiltinMacros.declareEnumMacro("LINKER_RESPONSE_FILE_FORMAT") as EnumMacroDeclaration<ResponseFileFormat>
11941195
public static let SWIFT_RESPONSE_FILE_PATH = BuiltinMacros.declarePathMacro("SWIFT_RESPONSE_FILE_PATH")
@@ -2443,6 +2444,7 @@ public final class BuiltinMacros {
24432444
_WRAPPER_PARENT_PATH,
24442445
_WRAPPER_RESOURCES_DIR,
24452446
__INPUT_FILE_LIST_PATH__,
2447+
HOST_RESPONSE_FILE_FORMAT,
24462448
LINKER_FILE_LIST_FORMAT,
24472449
LINKER_RESPONSE_FILE_FORMAT,
24482450
__ARCHS__,

Sources/SWBCore/Settings/Settings.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,6 +2350,8 @@ private class SettingsBuilder {
23502350
platformTable.push(BuiltinMacros.NATIVE_ARCH, literal: Architecture.hostStringValue ?? fallbackArch)
23512351
}
23522352

2353+
platformTable.push(BuiltinMacros.HOST_RESPONSE_FILE_FORMAT, literal: workspaceContext.core.hostOperatingSystem.defaultResponseFileFormat)
2354+
23532355
// Add the platform deployment target defaults, for real platforms.
23542356
//
23552357
// FIXME: For legacy compatibility, we only do this when configuring settings for a target. This distinction most likely isn't important, and should just be eliminated.

Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ public struct ClangPrefixInfo: Serializable, Hashable, Encodable, Sendable {
9292
}
9393
}
9494

95+
public struct ClangResponseFileInfo: SerializableCodable, Sendable {
96+
var attachmentPath: Path
97+
var format: ResponseFileFormat
98+
}
99+
95100
/// The minimal data we need to serialize to reconstruct `ClangSourceFileIndexingInfo` from `generateIndexingInfo`
96101
public struct ClangIndexingPayload: Serializable, Encodable, Sendable {
97102
let sourceFileIndex: Int
@@ -102,7 +107,7 @@ public struct ClangIndexingPayload: Serializable, Encodable, Sendable {
102107
let workingDir: Path
103108
let prefixInfo: ClangPrefixInfo?
104109
public let toolchains: [String]
105-
let responseFileAttachmentPaths: [Path: Path]
110+
let responseFileAttachmentPaths: [Path: ClangResponseFileInfo]
106111

107112
init(sourceFileIndex: Int,
108113
outputFileIndex: Int,
@@ -112,7 +117,7 @@ public struct ClangIndexingPayload: Serializable, Encodable, Sendable {
112117
workingDir: Path,
113118
prefixInfo: ClangPrefixInfo?,
114119
toolchains: [String],
115-
responseFileAttachmentPaths: [Path: Path]) {
120+
responseFileAttachmentPaths: [Path: ClangResponseFileInfo]) {
116121
self.sourceFileIndex = sourceFileIndex
117122
self.outputFileIndex = outputFileIndex
118123
self.sourceLanguageIndex = sourceLanguageIndex
@@ -202,7 +207,7 @@ public struct ClangSourceFileIndexingInfo: SourceFileIndexingInfo {
202207
static let skippedArgsWithoutValues = Set<ByteString>(["-M", "-MD", "-MMD", "-MG", "-MJ", "-MM", "-MP", "-MV", "-fmodules-validate-once-per-build-session"])
203208
static let skippedArgsWithValues = Set<ByteString>(["-MT", "-MF", "-MQ", "--serialize-diagnostics"])
204209

205-
public static func indexingCommandLine(from commandLine: [ByteString], workingDir: Path, prefixInfo: ClangPrefixInfo? = nil, addSupplementary: Bool = true, replaceCompile: Bool = true, responseFileMapping: [Path: Path]) -> [ByteString] {
210+
public static func indexingCommandLine(from commandLine: [ByteString], workingDir: Path, prefixInfo: ClangPrefixInfo? = nil, addSupplementary: Bool = true, replaceCompile: Bool = true, responseFileMapping: [Path: ClangResponseFileInfo]) -> [ByteString] {
206211
var result = [ByteString]()
207212
var iterator = commandLine.makeIterator()
208213
let _ = iterator.next() // Skip compiler path
@@ -234,8 +239,8 @@ public struct ClangSourceFileIndexingInfo: SourceFileIndexingInfo {
234239
} else if arg.bytes.starts(with: ByteString(stringLiteral: "-fbuild-session-file=").bytes) {
235240
// Skip
236241
} else if arg.starts(with: ByteString(unicodeScalarLiteral: "@")),
237-
let attachmentPath = responseFileMapping[Path(arg.asString.dropFirst())],
238-
let responseFileArgs = try? ResponseFiles.expandResponseFiles(["@\(attachmentPath.str)"], fileSystem: localFS, relativeTo: workingDir, format: .unixShellQuotedSpaceSeparated) {
242+
let attachment = responseFileMapping[Path(arg.asString.dropFirst())],
243+
let responseFileArgs = try? ResponseFiles.expandResponseFiles(["@\(attachment.attachmentPath.str)"], fileSystem: localFS, relativeTo: workingDir, format: attachment.format) {
239244
result.append(contentsOf: responseFileArgs.map { ByteString(encodingAsUTF8: $0) })
240245
} else {
241246
result.append(arg)
@@ -568,7 +573,7 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
568573
let inputs: [Path]
569574

570575
/// Maps response files in `flags` to the corresponding recorded attachment in the build description.
571-
let responseFileMapping: [Path: Path]
576+
let responseFileMapping: [Path: ClangResponseFileInfo]
572577

573578
}
574579

@@ -719,9 +724,10 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
719724
ctx.add(string: self.identifier)
720725

721726
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, format: .unixShellQuotedSpaceSeparated)), permissions: nil, logContents: true, preparesForIndexing: true, additionalTaskOrderingOptions: [.immediate, .ignorePhaseOrdering])
727+
let responseFileFormat = scope.evaluate(BuiltinMacros.HOST_RESPONSE_FILE_FORMAT)
728+
let attachmentPath = producer.writeFileSpec.constructFileTasks(CommandBuildContext(producer: producer, scope: scope, inputs: [], output: responseFilePath), delegate, contents: ByteString(encodingAsUTF8: ResponseFiles.responseFileContents(args: responseFileCommandLine, format: responseFileFormat)), permissions: nil, logContents: true, preparesForIndexing: true, additionalTaskOrderingOptions: [.immediate, .ignorePhaseOrdering])
723729

724-
return ConstantFlags(flags: regularCommandLine + ["@\(responseFilePath.str)"], headerSearchPaths: headerSearchPaths, inputs: [responseFilePath], responseFileMapping: [responseFilePath: attachmentPath])
730+
return ConstantFlags(flags: regularCommandLine + ["@\(responseFilePath.str)"], headerSearchPaths: headerSearchPaths, inputs: [responseFilePath], responseFileMapping: [responseFilePath: .init(attachmentPath: attachmentPath, format: responseFileFormat)])
725731
} else {
726732
return ConstantFlags(flags: commandLine, headerSearchPaths: headerSearchPaths, inputs: [], responseFileMapping: [:])
727733
}

Sources/SWBUtil/ProcessInfo.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,15 @@ public enum OperatingSystem: Hashable, Sendable {
167167
return .elf
168168
}
169169
}
170+
171+
public var defaultResponseFileFormat: ResponseFileFormat {
172+
switch self {
173+
case .windows:
174+
.windowsShellQuotedNewlineSeparated
175+
case .macOS, .iOS, .tvOS, .watchOS, .visionOS, .linux, .freebsd, .openbsd, .android, .unknown:
176+
.unixShellQuotedSpaceSeparated
177+
}
178+
}
170179
}
171180

172181
public enum ImageFormat {

Tests/SWBTaskConstructionTests/ClangResponseFileTaskConstructionTests.swift

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@ fileprivate struct ClangResponseFileTaskConstructionTests: CoreBasedTests {
6262
let responseFilePath = try #require(task.outputs.only)
6363

6464
// The command arguments in the response file vary vastly between different platforms, so just check for some basics present in the content.
65-
let contentAsString = contents.asString
66-
#expect(contentAsString.contains("-target "))
67-
#expect(contentAsString.contains("Test-generated-files.hmap"))
68-
#expect(contentAsString.contains("Test-own-target-headers.hmap"))
69-
#expect(contentAsString.contains("Test-all-target-headers.hmap"))
65+
if tester.core.hostOperatingSystem.defaultResponseFileFormat == .unixShellQuotedSpaceSeparated {
66+
let contentAsString = contents.asString
67+
#expect(contentAsString.contains("-target "))
68+
#expect(contentAsString.contains("Test-generated-files.hmap"))
69+
#expect(contentAsString.contains("Test-own-target-headers.hmap"))
70+
#expect(contentAsString.contains("Test-all-target-headers.hmap"))
71+
}
7072

7173
for name in ["a.c", "b.c", "c.c"] {
7274
results.checkTask(.matchRuleType("CompileC"), .matchRuleItemPattern(.suffix(name))) { compileTask in
@@ -166,20 +168,22 @@ fileprivate struct ClangResponseFileTaskConstructionTests: CoreBasedTests {
166168
let tester = try TaskConstructionTester(core, testProject)
167169
await tester.checkBuild(runDestination: .host) { results in
168170
results.checkWriteAuxiliaryFileTask(.matchRuleItemPattern(.suffix("-common-args.resp"))) { task, contents in
169-
let stringContents = contents.asString
170-
#expect(stringContents.contains("-target"))
171-
let blocksFlag = switch runDestination {
171+
if tester.core.hostOperatingSystem.defaultResponseFileFormat == .unixShellQuotedSpaceSeparated {
172+
let stringContents = contents.asString
173+
#expect(stringContents.contains("-target"))
174+
let blocksFlag = switch runDestination {
172175
case .macOS:
173176
"-fasm-blocks"
174177
case .linux:
175178
"-fblocks"
176179
default:
177180
" "
181+
}
182+
#expect(stringContents.contains(blocksFlag))
183+
#expect(!stringContents.contains("-MMD"))
184+
#expect(!stringContents.contains("-fcolor-diagnostics"))
185+
#expect(!stringContents.contains("-Wno-private-module"))
178186
}
179-
#expect(stringContents.contains(blocksFlag))
180-
#expect(!stringContents.contains("-MMD"))
181-
#expect(!stringContents.contains("-fcolor-diagnostics"))
182-
#expect(!stringContents.contains("-Wno-private-module"))
183187
for name in ["a", "b", "c"] {
184188
results.checkTask(.matchRuleType("CompileC"), .matchRuleItemPattern(.suffix(name + ".c"))) { compileTask in
185189
compileTask.checkCommandLineMatches(["-MMD", "-MT", "dependencies", "-MF", .suffix(name + ".d")])
@@ -349,8 +353,10 @@ fileprivate struct ClangResponseFileTaskConstructionTests: CoreBasedTests {
349353
let tester = try TaskConstructionTester(core, testProject)
350354
await tester.checkBuild(runDestination: .host) { results in
351355
results.checkWriteAuxiliaryFileTask(.matchRuleItemPattern(.suffix("-common-args.resp"))) { task, contents in
352-
let stringContents = contents.asString
353-
#expect(stringContents.contains("-Xclang -Wno-shorten-64-to-32"))
356+
if tester.core.hostOperatingSystem.defaultResponseFileFormat == .unixShellQuotedSpaceSeparated {
357+
let stringContents = contents.asString
358+
#expect(stringContents.contains("-Xclang -Wno-shorten-64-to-32"))
359+
}
354360
results.checkTask(.matchRuleType("CompileC"), .matchRuleItemPattern(.suffix("a.c"))) { compileTask in
355361
compileTask.checkCommandLineDoesNotContain("-Xclang")
356362
}

0 commit comments

Comments
 (0)