Skip to content

Commit b2eb29f

Browse files
committed
Create discovered dependencies file for emit-module jobs
Emit-module jobs might have different discovered dependencies and run in a different context where they need to get invalidated separately from the compile jobs. With the new key "emit-module-dependencies" in the output file map the build system can specify that it expects a makefile-style dependency file at the given path. rdar://91574616
1 parent b298fab commit b2eb29f

File tree

6 files changed

+106
-30
lines changed

6 files changed

+106
-30
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ public struct Driver {
281281
/// Path to the serialized diagnostics file of the emit-module task.
282282
let emitModuleSerializedDiagnosticsFilePath: VirtualPath.Handle?
283283

284+
/// Path to the discovered dependencies file of the emit-module task.
285+
let emitModuleDependenciesFilePath: VirtualPath.Handle?
286+
284287
/// Path to the Objective-C generated header.
285288
let objcGeneratedHeaderPath: VirtualPath.Handle?
286289

@@ -712,6 +715,14 @@ public struct Driver {
712715
emitModuleSeparately: emitModuleSeparately,
713716
outputFileMap: self.outputFileMap,
714717
moduleName: moduleOutputInfo.name)
718+
self.emitModuleDependenciesFilePath = try Self.computeSupplementaryOutputPath(
719+
&parsedOptions, type: .emitModuleDependencies, isOutputOptions: [.emitDependencies],
720+
outputPath: .emitModuleDependenciesPath,
721+
compilerOutputType: compilerOutputType,
722+
compilerMode: compilerMode,
723+
emitModuleSeparately: emitModuleSeparately,
724+
outputFileMap: self.outputFileMap,
725+
moduleName: moduleOutputInfo.name)
715726
// FIXME: -fixits-output-path
716727
self.objcGeneratedHeaderPath = try Self.computeSupplementaryOutputPath(
717728
&parsedOptions, type: .objcHeader, isOutputOptions: [.emitObjcHeader],
@@ -3003,6 +3014,14 @@ extension Driver {
30033014
outputType: type) {
30043015
return singleOutputPath
30053016
}
3017+
3018+
// Emit-module discovered dependencies are always specified as a single-output
3019+
// file
3020+
if type == .emitModuleDependencies,
3021+
let singleOutputPath = outputFileMap?.existingOutputForSingleInput(
3022+
outputType: type) {
3023+
return singleOutputPath
3024+
}
30063025

30073026
// If there is an output argument, derive the name from there.
30083027
if let outputPathArg = parsedOptions.getLastArgument(.o) {

Sources/SwiftDriver/Jobs/CompileJob.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,12 @@ extension Driver {
8989
}
9090
case .swiftModule:
9191
return compilerMode.isSingleCompilation && moduleOutputInfo.output?.isTopLevel ?? false
92-
case .swift, .image, .dSYM, .dependencies, .autolink, .swiftDocumentation, .swiftInterface,
93-
.privateSwiftInterface, .swiftSourceInfoFile, .diagnostics, .emitModuleDiagnostics,
94-
.objcHeader, .swiftDeps, .remap, .tbd, .moduleTrace, .yamlOptimizationRecord,
95-
.bitstreamOptimizationRecord, .pcm, .pch, .clangModuleMap, .jsonCompilerFeatures,
96-
.jsonTargetInfo, .jsonSwiftArtifacts, .indexUnitOutputPath, .modDepCache,
97-
.jsonAPIBaseline, .jsonABIBaseline, nil:
92+
case .swift, .image, .dSYM, .dependencies, .emitModuleDependencies, .autolink,
93+
.swiftDocumentation, .swiftInterface, .privateSwiftInterface, .swiftSourceInfoFile,
94+
.diagnostics, .emitModuleDiagnostics, .objcHeader, .swiftDeps, .remap, .tbd,
95+
.moduleTrace, .yamlOptimizationRecord, .bitstreamOptimizationRecord, .pcm, .pch,
96+
.clangModuleMap, .jsonCompilerFeatures, .jsonTargetInfo, .jsonSwiftArtifacts,
97+
.indexUnitOutputPath, .modDepCache, .jsonAPIBaseline, .jsonABIBaseline, nil:
9898
return false
9999
}
100100
}
@@ -446,10 +446,11 @@ extension FileType {
446446
case .jsonCompilerFeatures:
447447
return .emitSupportedFeatures
448448

449-
case .swift, .dSYM, .autolink, .dependencies, .swiftDocumentation, .pcm,
450-
.diagnostics, .emitModuleDiagnostics, .objcHeader, .image, .swiftDeps, .moduleTrace, .tbd,
451-
.yamlOptimizationRecord, .bitstreamOptimizationRecord, .swiftInterface,
452-
.privateSwiftInterface, .swiftSourceInfoFile, .clangModuleMap, .jsonSwiftArtifacts,
449+
case .swift, .dSYM, .autolink, .dependencies, .emitModuleDependencies,
450+
.swiftDocumentation, .pcm, .diagnostics, .emitModuleDiagnostics,
451+
.objcHeader, .image, .swiftDeps, .moduleTrace, .tbd, .yamlOptimizationRecord,
452+
.bitstreamOptimizationRecord, .swiftInterface, .privateSwiftInterface,
453+
.swiftSourceInfoFile, .clangModuleMap, .jsonSwiftArtifacts,
453454
.indexUnitOutputPath, .modDepCache, .jsonAPIBaseline, .jsonABIBaseline:
454455
fatalError("Output type can never be a primary output")
455456
}

Sources/SwiftDriver/Jobs/EmitModuleJob.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ extension Driver {
4040
}
4141

4242
addSupplementalOutput(path: emitModuleSerializedDiagnosticsFilePath, flag: "-serialize-diagnostics-path", type: .emitModuleDiagnostics)
43+
44+
addSupplementalOutput(path: emitModuleDependenciesFilePath, flag: "-emit-dependencies-path", type: .emitModuleDependencies)
4345

4446
// Skip files created by other jobs when emitting a module and building at the same time
4547
if emitModuleSeparately && compilerOutputType != .swiftModule {

Sources/SwiftDriver/Utilities/FileType.swift

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public enum FileType: String, Hashable, CaseIterable, Codable {
7777

7878
/// Serialized diagnostics produced by module-generation
7979
case emitModuleDiagnostics = "emit-module.dia"
80+
81+
/// Serialized diagnostics produced by module-generation
82+
case emitModuleDependencies = "emit-module.d"
8083

8184
/// Objective-C header
8285
case objcHeader = "h"
@@ -150,9 +153,10 @@ public enum FileType: String, Hashable, CaseIterable, Codable {
150153
extension FileType: CustomStringConvertible {
151154
public var description: String {
152155
switch self {
153-
case .swift, .sil, .sib, .image, .dSYM, .dependencies, .autolink,
154-
.swiftModule, .swiftDocumentation, .swiftInterface, .swiftSourceInfoFile, .assembly,
155-
.remap, .tbd, .pcm, .pch, .clangModuleMap:
156+
case .swift, .sil, .sib, .image, .dSYM, .dependencies, .emitModuleDependencies,
157+
.autolink, .swiftModule, .swiftDocumentation, .swiftInterface,
158+
.swiftSourceInfoFile, .assembly, .remap, .tbd, .pcm, .pch,
159+
.clangModuleMap:
156160
return rawValue
157161
case .object:
158162
return "object"
@@ -238,11 +242,13 @@ extension FileType {
238242
return true
239243
case .object, .pch, .ast, .llvmIR, .llvmBitcode, .assembly, .swiftModule,
240244
.importedModules, .indexData, .remap, .dSYM, .autolink, .dependencies,
241-
.swiftDocumentation, .pcm, .diagnostics, .emitModuleDiagnostics, .objcHeader, .image,
242-
.swiftDeps, .moduleTrace, .tbd, .yamlOptimizationRecord, .bitstreamOptimizationRecord,
243-
.swiftInterface, .privateSwiftInterface, .swiftSourceInfoFile, .jsonDependencies,
244-
.clangModuleMap, .jsonTargetInfo, .jsonCompilerFeatures, .jsonSwiftArtifacts,
245-
.indexUnitOutputPath, .modDepCache, .jsonAPIBaseline, .jsonABIBaseline:
245+
.emitModuleDependencies, .swiftDocumentation, .pcm, .diagnostics,
246+
.emitModuleDiagnostics, .objcHeader, .image, .swiftDeps, .moduleTrace,
247+
.tbd, .yamlOptimizationRecord, .bitstreamOptimizationRecord,
248+
.swiftInterface, .privateSwiftInterface, .swiftSourceInfoFile,
249+
.jsonDependencies, .clangModuleMap, .jsonTargetInfo, .jsonCompilerFeatures,
250+
.jsonSwiftArtifacts, .indexUnitOutputPath, .modDepCache, .jsonAPIBaseline,
251+
.jsonABIBaseline:
246252
return false
247253
}
248254
}
@@ -275,6 +281,8 @@ extension FileType {
275281
return "dSYM"
276282
case .dependencies:
277283
return "dependencies"
284+
case .emitModuleDependencies:
285+
return "emit-module-dependencies"
278286
case .autolink:
279287
return "autolink"
280288
case .swiftModule:
@@ -350,11 +358,11 @@ extension FileType {
350358
extension FileType {
351359
var isTextual: Bool {
352360
switch self {
353-
case .swift, .sil, .dependencies, .assembly, .ast, .raw_sil, .llvmIR,
354-
.objcHeader, .autolink, .importedModules, .tbd, .moduleTrace,
355-
.yamlOptimizationRecord, .swiftInterface, .privateSwiftInterface,
356-
.jsonDependencies, .clangModuleMap, .jsonCompilerFeatures,
357-
.jsonTargetInfo, .jsonSwiftArtifacts, .jsonAPIBaseline, .jsonABIBaseline:
361+
case .swift, .sil, .dependencies, .emitModuleDependencies, .assembly, .ast,
362+
.raw_sil, .llvmIR,.objcHeader, .autolink, .importedModules, .tbd,
363+
.moduleTrace, .yamlOptimizationRecord, .swiftInterface, .privateSwiftInterface,
364+
.jsonDependencies, .clangModuleMap, .jsonCompilerFeatures, .jsonTargetInfo,
365+
.jsonSwiftArtifacts, .jsonAPIBaseline, .jsonABIBaseline:
358366
return true
359367
case .image, .object, .dSYM, .pch, .sib, .raw_sib, .swiftModule,
360368
.swiftDocumentation, .swiftSourceInfoFile, .llvmBitcode, .diagnostics,
@@ -370,13 +378,14 @@ extension FileType {
370378
switch self {
371379
case .assembly, .llvmIR, .llvmBitcode, .object:
372380
return true
373-
case .swift, .sil, .sib, .ast, .image, .dSYM, .dependencies, .autolink,
374-
.swiftModule, .swiftDocumentation, .swiftInterface, .privateSwiftInterface,
375-
.swiftSourceInfoFile, .raw_sil, .raw_sib, .diagnostics, .emitModuleDiagnostics, .objcHeader, .swiftDeps, .remap,
376-
.importedModules, .tbd, .moduleTrace, .indexData, .yamlOptimizationRecord, .modDepCache,
377-
.bitstreamOptimizationRecord, .pcm, .pch, .jsonDependencies, .clangModuleMap,
378-
.jsonCompilerFeatures, .jsonTargetInfo, .jsonSwiftArtifacts, .indexUnitOutputPath, .jsonAPIBaseline,
379-
.jsonABIBaseline:
381+
case .swift, .sil, .sib, .ast, .image, .dSYM, .dependencies, .emitModuleDependencies,
382+
.autolink, .swiftModule, .swiftDocumentation, .swiftInterface,
383+
.privateSwiftInterface, .swiftSourceInfoFile, .raw_sil, .raw_sib,
384+
.diagnostics, .emitModuleDiagnostics, .objcHeader, .swiftDeps, .remap,
385+
.importedModules, .tbd, .moduleTrace, .indexData, .yamlOptimizationRecord,
386+
.modDepCache, .bitstreamOptimizationRecord, .pcm, .pch, .jsonDependencies,
387+
.clangModuleMap, .jsonCompilerFeatures, .jsonTargetInfo, .jsonSwiftArtifacts,
388+
.indexUnitOutputPath, .jsonAPIBaseline, .jsonABIBaseline:
380389
return false
381390
}
382391
}

Sources/SwiftOptions/ExtraOptions.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extension Option {
2020
public static let emitModuleSeparatelyWMO: Option = Option("-emit-module-separately-wmo", .flag, attributes: [.helpHidden], helpText: "Emit module files as a distinct job in wmo builds")
2121
public static let noEmitModuleSeparatelyWMO: Option = Option("-no-emit-module-separately-wmo", .flag, attributes: [.helpHidden], helpText: "Emit module files as a distinct job in wmo builds")
2222
public static let emitModuleSerializeDiagnosticsPath: Option = Option("-emit-module-serialize-diagnostics-path", .separate, attributes: [.argumentIsPath, .supplementaryOutput], metaVar: "<path>", helpText: "Emit a serialized diagnostics file for the emit-module task to <path>")
23+
public static let emitModuleDependenciesPath: Option = Option("-emit-module-dependencies-path", .separate, attributes: [.argumentIsPath, .supplementaryOutput], metaVar: "<path>", helpText: "Emit a discovered dependencies file for the emit-module task to <path>")
2324
public static let useFrontendParseableOutput: Option = Option("-use-frontend-parseable-output", .flag, attributes: [.helpHidden], helpText: "Emit parseable-output from swift-frontend jobs instead of from the driver")
2425

2526
// API digester operations

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,50 @@ final class SwiftDriverTests: XCTestCase {
727727
}
728728
}
729729
}
730+
731+
func testEmitModuleSeparatelyDependenciesPath() throws {
732+
try withTemporaryFile { fileMapFile in
733+
let outputMapContents = """
734+
{
735+
"": {
736+
"dependencies": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.d",
737+
"emit-module-dependencies": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.emit-module.d"
738+
},
739+
"foo.swift": {
740+
"dependencies": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/foo.d"
741+
}
742+
}
743+
"""
744+
try localFileSystem.writeFileContents(fileMapFile.path) { $0 <<< outputMapContents }
745+
746+
// Plain (batch/single-file) compile
747+
do {
748+
var driver = try Driver(args: ["swiftc", "foo.swift", "-emit-module", "-output-file-map", fileMapFile.path.pathString,
749+
"-emit-library", "-module-name", "Test", "-emit-dependencies"])
750+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
751+
XCTAssertEqual(plannedJobs.count, 3)
752+
XCTAssertTrue(plannedJobs[0].kind == .emitModule)
753+
XCTAssertTrue(plannedJobs[1].kind == .compile)
754+
XCTAssertTrue(plannedJobs[2].kind == .link)
755+
XCTAssertTrue(plannedJobs[0].commandLine.contains(subsequence: ["-emit-dependencies-path", .path(.absolute(.init("/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.emit-module.d")))]))
756+
XCTAssertTrue(plannedJobs[1].commandLine.contains(subsequence: ["-emit-dependencies-path", .path(.absolute(.init("/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/foo.d")))]))
757+
}
758+
759+
// WMO
760+
do {
761+
var driver = try Driver(args: ["swiftc", "foo.swift", "-whole-module-optimization", "-emit-module",
762+
"-output-file-map", fileMapFile.path.pathString, "-disable-cmo",
763+
"-emit-library", "-module-name", "Test", "-emit-dependencies"])
764+
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
765+
XCTAssertEqual(plannedJobs.count, 3)
766+
XCTAssertTrue(plannedJobs[0].kind == .compile)
767+
XCTAssertTrue(plannedJobs[1].kind == .emitModule)
768+
XCTAssertTrue(plannedJobs[2].kind == .link)
769+
XCTAssertTrue(plannedJobs[0].commandLine.contains(subsequence: ["-emit-dependencies-path", .path(.absolute(.init("/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.d")))]))
770+
XCTAssertTrue(plannedJobs[1].commandLine.contains(subsequence: ["-emit-dependencies-path", .path(.absolute(.init("/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.emit-module.d")))]))
771+
}
772+
}
773+
}
730774

731775
func testOutputFileMapLoading() throws {
732776
let contents = """

0 commit comments

Comments
 (0)