Skip to content

Commit 0055bc6

Browse files
committed
Group supplementary module outputs
This should have no actual impact on compilation. The idea is that we are grouping the supplementary outputs that are specific to a given target. This will allow us to store two of them, one for the target and one for the target-variant. The end goal being that we can emit the target variant interface bits in the same driver invocation that generates the zippered object files.
1 parent bfc9c09 commit 0055bc6

File tree

6 files changed

+174
-101
lines changed

6 files changed

+174
-101
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 128 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -376,27 +376,130 @@ public struct Driver {
376376
/// Path to the TBD file (text-based dylib).
377377
let tbdPath: VirtualPath.Handle?
378378

379-
/// Path to the module documentation file.
380-
let moduleDocOutputPath: VirtualPath.Handle?
379+
/// Target-specific supplemental output file paths
380+
struct SupplementalModuleTargetOutputPaths {
381+
/// Path to the module documentation file.
382+
let moduleDocOutputPath: VirtualPath.Handle?
381383

382-
/// Path to the Swift interface file.
383-
let swiftInterfacePath: VirtualPath.Handle?
384+
/// Path to the Swift interface file.
385+
let swiftInterfacePath: VirtualPath.Handle?
384386

385-
/// Path to the Swift private interface file.
386-
let swiftPrivateInterfacePath: VirtualPath.Handle?
387+
/// Path to the Swift private interface file.
388+
let swiftPrivateInterfacePath: VirtualPath.Handle?
387389

388-
/// Path to the Swift package interface file.
389-
let swiftPackageInterfacePath: VirtualPath.Handle?
390+
/// Path to the Swift package interface file.
391+
let swiftPackageInterfacePath: VirtualPath.Handle?
392+
393+
/// Path to the Swift module source information file.
394+
let moduleSourceInfoPath: VirtualPath.Handle?
395+
}
396+
397+
private static func computeModuleOutputPaths(
398+
_ parsedOptions: inout ParsedOptions,
399+
moduleName: String,
400+
packageName: String?,
401+
moduleOutputInfo: ModuleOutputInfo,
402+
compilerOutputType: FileType?,
403+
compilerMode: CompilerMode,
404+
emitModuleSeparately: Bool,
405+
outputFileMap: OutputFileMap?,
406+
projectDirectory: VirtualPath.Handle?) throws -> SupplementalModuleTargetOutputPaths {
407+
let moduleDocOutputPath = try Self.computeModuleDocOutputPath(
408+
&parsedOptions,
409+
moduleOutputPath: moduleOutputInfo.output?.outputPath,
410+
compilerOutputType: compilerOutputType,
411+
compilerMode: compilerMode,
412+
outputFileMap: outputFileMap,
413+
moduleName: moduleOutputInfo.name)
414+
415+
let moduleSourceInfoPath = try Self.computeModuleSourceInfoOutputPath(
416+
&parsedOptions,
417+
moduleOutputPath: moduleOutputInfo.output?.outputPath,
418+
compilerOutputType: compilerOutputType,
419+
compilerMode: compilerMode,
420+
outputFileMap: outputFileMap,
421+
moduleName: moduleOutputInfo.name,
422+
projectDirectory: projectDirectory)
423+
424+
// ---------------------
425+
// Swift interface paths
426+
let swiftInterfacePath = try Self.computeSupplementaryOutputPath(
427+
&parsedOptions, type: .swiftInterface, isOutputOptions: [.emitModuleInterface],
428+
outputPath: .emitModuleInterfacePath,
429+
compilerOutputType: compilerOutputType,
430+
compilerMode: compilerMode,
431+
emitModuleSeparately: emitModuleSeparately,
432+
outputFileMap: outputFileMap,
433+
moduleName: moduleOutputInfo.name)
434+
435+
let givenPrivateInterfacePath = try Self.computeSupplementaryOutputPath(
436+
&parsedOptions, type: .privateSwiftInterface, isOutputOptions: [],
437+
outputPath: .emitPrivateModuleInterfacePath,
438+
compilerOutputType: compilerOutputType,
439+
compilerMode: compilerMode,
440+
emitModuleSeparately: emitModuleSeparately,
441+
outputFileMap: outputFileMap,
442+
moduleName: moduleOutputInfo.name)
443+
let givenPackageInterfacePath = try Self.computeSupplementaryOutputPath(
444+
&parsedOptions, type: .packageSwiftInterface, isOutputOptions: [],
445+
outputPath: .emitPackageModuleInterfacePath,
446+
compilerOutputType: compilerOutputType,
447+
compilerMode: compilerMode,
448+
emitModuleSeparately: emitModuleSeparately,
449+
outputFileMap: outputFileMap,
450+
moduleName: moduleOutputInfo.name)
451+
452+
// Always emit the private swift interface if a public interface is emitted.
453+
// With the introduction of features like @_spi_available, we may print
454+
// public and private interfaces differently even from the same codebase.
455+
// For this reason, we should always print private interfaces so that we
456+
// don’t mix the public interfaces with private Clang modules.
457+
let swiftPrivateInterfacePath: VirtualPath.Handle?
458+
if let privateInterfacePath = givenPrivateInterfacePath {
459+
swiftPrivateInterfacePath = privateInterfacePath
460+
} else if let swiftInterfacePath = swiftInterfacePath {
461+
swiftPrivateInterfacePath = try VirtualPath.lookup(swiftInterfacePath)
462+
.replacingExtension(with: .privateSwiftInterface).intern()
463+
} else {
464+
swiftPrivateInterfacePath = nil
465+
}
466+
467+
let swiftPackageInterfacePath: VirtualPath.Handle?
468+
if let packageName = packageName,
469+
!packageName.isEmpty {
470+
// Generate a package interface if built with -package-name required for
471+
// decls with the `package` access level. The `.package.swiftinterface`
472+
// contains package decls as well as SPI and public decls (superset of a
473+
// private interface).
474+
if let givenPackageInterfacePath = givenPackageInterfacePath {
475+
swiftPackageInterfacePath = givenPackageInterfacePath
476+
} else if let swiftInterfacePath = swiftInterfacePath {
477+
swiftPackageInterfacePath = try VirtualPath.lookup(swiftInterfacePath)
478+
.replacingExtension(with: .packageSwiftInterface).intern()
479+
} else {
480+
swiftPackageInterfacePath = nil
481+
}
482+
} else {
483+
swiftPackageInterfacePath = nil
484+
}
485+
486+
return SupplementalModuleTargetOutputPaths(
487+
moduleDocOutputPath: moduleDocOutputPath,
488+
swiftInterfacePath: swiftInterfacePath,
489+
swiftPrivateInterfacePath: swiftPrivateInterfacePath,
490+
swiftPackageInterfacePath: swiftPackageInterfacePath,
491+
moduleSourceInfoPath: moduleSourceInfoPath)
492+
}
493+
494+
/// Structure storing paths to supplemental outputs for the target module
495+
let moduleOutputPaths: SupplementalModuleTargetOutputPaths
390496

391497
/// File type for the optimization record.
392498
let optimizationRecordFileType: FileType?
393499

394500
/// Path to the optimization record.
395501
let optimizationRecordPath: VirtualPath.Handle?
396502

397-
/// Path to the Swift module source information file.
398-
let moduleSourceInfoPath: VirtualPath.Handle?
399-
400503
/// Path to the module's digester baseline file.
401504
let digesterBaselinePath: VirtualPath.Handle?
402505

@@ -1023,24 +1126,22 @@ public struct Driver {
10231126
emitModuleSeparately: emitModuleSeparately,
10241127
outputFileMap: self.outputFileMap,
10251128
moduleName: moduleOutputInfo.name)
1026-
self.moduleDocOutputPath = try Self.computeModuleDocOutputPath(
1027-
&parsedOptions, moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
1028-
compilerOutputType: compilerOutputType,
1029-
compilerMode: compilerMode,
1030-
outputFileMap: self.outputFileMap,
1031-
moduleName: moduleOutputInfo.name)
10321129

10331130
let projectDirectory = Self.computeProjectDirectoryPath(
1034-
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
1131+
moduleOutputPath: moduleOutputInfo.output?.outputPath,
10351132
fileSystem: self.fileSystem)
1036-
self.moduleSourceInfoPath = try Self.computeModuleSourceInfoOutputPath(
1037-
&parsedOptions,
1038-
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
1039-
compilerOutputType: compilerOutputType,
1040-
compilerMode: compilerMode,
1041-
outputFileMap: self.outputFileMap,
1042-
moduleName: moduleOutputInfo.name,
1043-
projectDirectory: projectDirectory)
1133+
1134+
self.moduleOutputPaths = try Self.computeModuleOutputPaths(
1135+
&parsedOptions,
1136+
moduleName: moduleOutputInfo.name,
1137+
packageName: self.packageName,
1138+
moduleOutputInfo: self.moduleOutputInfo,
1139+
compilerOutputType: compilerOutputType,
1140+
compilerMode: compilerMode,
1141+
emitModuleSeparately: emitModuleSeparately,
1142+
outputFileMap: self.outputFileMap,
1143+
projectDirectory: projectDirectory)
1144+
10441145
self.digesterBaselinePath = try Self.computeDigesterBaselineOutputPath(
10451146
&parsedOptions,
10461147
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
@@ -1050,59 +1151,6 @@ public struct Driver {
10501151
outputFileMap: self.outputFileMap,
10511152
moduleName: moduleOutputInfo.name,
10521153
projectDirectory: projectDirectory)
1053-
self.swiftInterfacePath = try Self.computeSupplementaryOutputPath(
1054-
&parsedOptions, type: .swiftInterface, isOutputOptions: [.emitModuleInterface],
1055-
outputPath: .emitModuleInterfacePath,
1056-
compilerOutputType: compilerOutputType,
1057-
compilerMode: compilerMode,
1058-
emitModuleSeparately: emitModuleSeparately,
1059-
outputFileMap: self.outputFileMap,
1060-
moduleName: moduleOutputInfo.name)
1061-
let givenPrivateInterfacePath = try Self.computeSupplementaryOutputPath(
1062-
&parsedOptions, type: .privateSwiftInterface, isOutputOptions: [],
1063-
outputPath: .emitPrivateModuleInterfacePath,
1064-
compilerOutputType: compilerOutputType,
1065-
compilerMode: compilerMode,
1066-
emitModuleSeparately: emitModuleSeparately,
1067-
outputFileMap: self.outputFileMap,
1068-
moduleName: moduleOutputInfo.name)
1069-
let givenPackageInterfacePath = try Self.computeSupplementaryOutputPath(
1070-
&parsedOptions, type: .packageSwiftInterface, isOutputOptions: [],
1071-
outputPath: .emitPackageModuleInterfacePath,
1072-
compilerOutputType: compilerOutputType,
1073-
compilerMode: compilerMode,
1074-
emitModuleSeparately: emitModuleSeparately,
1075-
outputFileMap: self.outputFileMap,
1076-
moduleName: moduleOutputInfo.name)
1077-
1078-
// Always emitting private swift interfaces if public interfaces are emitted.'
1079-
// With the introduction of features like @_spi_available, we may print public
1080-
// and private interfaces differently even from the same codebase. For this reason,
1081-
// we should always print private interfaces so that we don’t mix the public interfaces
1082-
// with private Clang modules.
1083-
if let swiftInterfacePath = self.swiftInterfacePath,
1084-
givenPrivateInterfacePath == nil {
1085-
self.swiftPrivateInterfacePath = try VirtualPath.lookup(swiftInterfacePath)
1086-
.replacingExtension(with: .privateSwiftInterface).intern()
1087-
} else {
1088-
self.swiftPrivateInterfacePath = givenPrivateInterfacePath
1089-
}
1090-
1091-
if let packageNameInput = parsedOptions.getLastArgument(Option.packageName),
1092-
!packageNameInput.asSingle.isEmpty {
1093-
// Generate a package interface if built with `-package-name` required for decls
1094-
// with the `package` access level. The .package.swiftinterface contains package
1095-
// decls as well as SPI and public decls (superset of a private interface).
1096-
if let publicInterfacePath = self.swiftInterfacePath,
1097-
givenPackageInterfacePath == nil {
1098-
self.swiftPackageInterfacePath = try VirtualPath.lookup(publicInterfacePath)
1099-
.replacingExtension(with: .packageSwiftInterface).intern()
1100-
} else {
1101-
self.swiftPackageInterfacePath = givenPackageInterfacePath
1102-
}
1103-
} else {
1104-
self.swiftPackageInterfacePath = nil
1105-
}
11061154

11071155
var optimizationRecordFileType = FileType.yamlOptimizationRecord
11081156
if let argument = parsedOptions.getLastArgument(.saveOptimizationRecordEQ)?.asSingle {
@@ -1151,7 +1199,7 @@ public struct Driver {
11511199
Self.validateDigesterArgs(&parsedOptions,
11521200
moduleOutputInfo: moduleOutputInfo,
11531201
digesterMode: self.digesterMode,
1154-
swiftInterfacePath: self.swiftInterfacePath,
1202+
swiftInterfacePath: self.moduleOutputPaths.swiftInterfacePath,
11551203
diagnosticEngine: diagnosticsEngine)
11561204

11571205
try verifyOutputOptions()

Sources/SwiftDriver/Jobs/APIDigesterJobs.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ extension Driver {
4646
var commandLine = [Job.ArgTemplate]()
4747
commandLine.appendFlag("-dump-sdk")
4848

49-
try addCommonDigesterOptions(&commandLine, modulePath: modulePath, mode: mode)
49+
try addCommonDigesterOptions(&commandLine,
50+
modulePath: modulePath,
51+
swiftModuleInterfacePath: self.moduleOutputPaths.swiftInterfacePath,
52+
mode: mode)
5053

5154
commandLine.appendFlag(.o)
5255
commandLine.appendPath(VirtualPath.lookup(outputPath))
@@ -74,7 +77,11 @@ extension Driver {
7477
}
7578
guard let currentABI = getDescriptorPath(for: mode) else {
7679
// we don't have existing descriptor to use so we have to load the module from interface/swiftmodule
77-
return try digesterCompareToBaselineJob(modulePath: modulePath, baselinePath: baselinePath, mode: digesterMode)
80+
return try digesterCompareToBaselineJob(
81+
modulePath: modulePath,
82+
swiftModuleInterfacePath: self.moduleOutputPaths.swiftInterfacePath,
83+
baselinePath: baselinePath,
84+
mode: digesterMode)
7885
}
7986
var commandLine = [Job.ArgTemplate]()
8087
commandLine.appendFlag("-diagnose-sdk")
@@ -105,14 +112,20 @@ extension Driver {
105112
)
106113
}
107114

108-
mutating func digesterCompareToBaselineJob(modulePath: VirtualPath.Handle, baselinePath: VirtualPath.Handle, mode: DigesterMode) throws -> Job {
115+
mutating func digesterCompareToBaselineJob(modulePath: VirtualPath.Handle,
116+
swiftModuleInterfacePath: VirtualPath.Handle?,
117+
baselinePath: VirtualPath.Handle,
118+
mode: DigesterMode) throws -> Job {
109119
var commandLine = [Job.ArgTemplate]()
110120
commandLine.appendFlag("-diagnose-sdk")
111121
commandLine.appendFlag("-disable-fail-on-error")
112122
commandLine.appendFlag("-baseline-path")
113123
commandLine.appendPath(VirtualPath.lookup(baselinePath))
114124

115-
try addCommonDigesterOptions(&commandLine, modulePath: modulePath, mode: mode)
125+
try addCommonDigesterOptions(&commandLine,
126+
modulePath: modulePath,
127+
swiftModuleInterfacePath: swiftModuleInterfacePath,
128+
mode: mode)
116129

117130
var serializedDiagnosticsPath: VirtualPath.Handle?
118131
if let arg = parsedOptions.getLastArgument(.serializeBreakingChangesPath)?.asSingle {
@@ -130,7 +143,7 @@ extension Driver {
130143
var inputs: [TypedVirtualPath] = [.init(file: modulePath, type: .swiftModule),
131144
.init(file: baselinePath, type: mode.baselineFileType)]
132145
// If a module interface was emitted, treat it as an input in ABI mode.
133-
if let interfacePath = self.swiftInterfacePath, mode == .abi {
146+
if let interfacePath = swiftModuleInterfacePath, mode == .abi {
134147
inputs.append(.init(file: interfacePath, type: .swiftInterface))
135148
}
136149

@@ -147,6 +160,7 @@ extension Driver {
147160

148161
private mutating func addCommonDigesterOptions(_ commandLine: inout [Job.ArgTemplate],
149162
modulePath: VirtualPath.Handle,
163+
swiftModuleInterfacePath: VirtualPath.Handle?,
150164
mode: DigesterMode) throws {
151165
commandLine.appendFlag("-module")
152166
commandLine.appendFlag(moduleOutputInfo.name)
@@ -160,7 +174,7 @@ extension Driver {
160174
let searchPath = VirtualPath.lookup(modulePath).parentDirectory
161175
commandLine.appendFlag(.I)
162176
commandLine.appendPath(searchPath)
163-
if let interfacePath = self.swiftInterfacePath {
177+
if let interfacePath = swiftModuleInterfacePath {
164178
let interfaceSearchPath = VirtualPath.lookup(interfacePath).parentDirectory
165179
if interfaceSearchPath != searchPath {
166180
commandLine.appendFlag(.I)

Sources/SwiftDriver/Jobs/CompileJob.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ extension Driver {
277277
primaryInputs: primaryInputs,
278278
inputsGeneratingCodeCount: inputsGeneratingCodeCount,
279279
inputOutputMap: &inputOutputMap,
280+
moduleOutputInfo: self.moduleOutputInfo,
281+
moduleOutputPaths: self.moduleOutputPaths,
280282
includeModuleTracePath: emitModuleTrace,
281283
indexFilePath: indexFilePath)
282284

Sources/SwiftDriver/Jobs/EmitModuleJob.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extension Driver {
1717
mutating func addCommonModuleOptions(
1818
commandLine: inout [Job.ArgTemplate],
1919
outputs: inout [TypedVirtualPath],
20+
moduleOutputPaths: SupplementalModuleTargetOutputPaths,
2021
isMergeModule: Bool
2122
) throws {
2223
// Add supplemental outputs.
@@ -28,12 +29,12 @@ extension Driver {
2829
outputs.append(.init(file: path, type: type))
2930
}
3031

31-
addSupplementalOutput(path: moduleDocOutputPath, flag: "-emit-module-doc-path", type: .swiftDocumentation)
32-
addSupplementalOutput(path: moduleSourceInfoPath, flag: "-emit-module-source-info-path", type: .swiftSourceInfoFile)
33-
addSupplementalOutput(path: swiftInterfacePath, flag: "-emit-module-interface-path", type: .swiftInterface)
34-
addSupplementalOutput(path: swiftPrivateInterfacePath, flag: "-emit-private-module-interface-path", type: .privateSwiftInterface)
32+
addSupplementalOutput(path: moduleOutputPaths.moduleDocOutputPath, flag: "-emit-module-doc-path", type: .swiftDocumentation)
33+
addSupplementalOutput(path: moduleOutputPaths.moduleSourceInfoPath, flag: "-emit-module-source-info-path", type: .swiftSourceInfoFile)
34+
addSupplementalOutput(path: moduleOutputPaths.swiftInterfacePath, flag: "-emit-module-interface-path", type: .swiftInterface)
35+
addSupplementalOutput(path: moduleOutputPaths.swiftPrivateInterfacePath, flag: "-emit-private-module-interface-path", type: .privateSwiftInterface)
3536
if let pkgName = packageName, !pkgName.isEmpty {
36-
addSupplementalOutput(path: swiftPackageInterfacePath, flag: "-emit-package-module-interface-path", type: .packageSwiftInterface)
37+
addSupplementalOutput(path: moduleOutputPaths.swiftPackageInterfacePath, flag: "-emit-package-module-interface-path", type: .packageSwiftInterface)
3738
}
3839
addSupplementalOutput(path: objcGeneratedHeaderPath, flag: "-emit-objc-header-path", type: .objcHeader)
3940
addSupplementalOutput(path: tbdPath, flag: "-emit-tbd-path", type: .tbd)
@@ -102,7 +103,7 @@ extension Driver {
102103
try addCommonFrontendOptions(commandLine: &commandLine, inputs: &inputs, kind: .emitModule)
103104
// FIXME: Add MSVC runtime library flags
104105

105-
try addCommonModuleOptions(commandLine: &commandLine, outputs: &outputs, isMergeModule: false)
106+
try addCommonModuleOptions(commandLine: &commandLine, outputs: &outputs, moduleOutputPaths: moduleOutputPaths,isMergeModule: false)
106107
try addCommonSymbolGraphOptions(commandLine: &commandLine)
107108

108109
try commandLine.appendLast(.checkApiAvailabilityOnly, from: &parsedOptions)

0 commit comments

Comments
 (0)