Skip to content

Commit 7e7543b

Browse files
committed
Introduce -emit-api-descriptor-path option.
This option and its argument, when specified on the driver command line, should be passed through to jobs that emit modules and have access to the whole module. Resolves rdar://116538520
1 parent 04f9f28 commit 7e7543b

File tree

7 files changed

+80
-6
lines changed

7 files changed

+80
-6
lines changed

Sources/SwiftDriver/Driver/Driver.swift

+12
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ public struct Driver {
347347
/// Path to the module's digester baseline file.
348348
let digesterBaselinePath: VirtualPath.Handle?
349349

350+
/// Path to the emitted API descriptor file.
351+
let apiDescriptorFilePath: VirtualPath.Handle?
352+
350353
/// The mode the API digester should run in.
351354
let digesterMode: DigesterMode
352355

@@ -954,6 +957,15 @@ public struct Driver {
954957
outputFileMap: self.outputFileMap,
955958
moduleName: moduleOutputInfo.name)
956959

960+
self.apiDescriptorFilePath = try Self.computeSupplementaryOutputPath(
961+
&parsedOptions, type: .jsonAPIDescriptor, isOutputOptions: [],
962+
outputPath: .emitApiDescriptorPath,
963+
compilerOutputType: compilerOutputType,
964+
compilerMode: compilerMode,
965+
emitModuleSeparately: emitModuleSeparately,
966+
outputFileMap: self.outputFileMap,
967+
moduleName: moduleOutputInfo.name)
968+
957969
Self.validateDigesterArgs(&parsedOptions,
958970
moduleOutputInfo: moduleOutputInfo,
959971
digesterMode: self.digesterMode,

Sources/SwiftDriver/Jobs/CompileJob.swift

+2-3
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ extension Driver {
9797
.moduleTrace, .yamlOptimizationRecord, .bitstreamOptimizationRecord, .pcm, .pch,
9898
.clangModuleMap, .jsonCompilerFeatures, .jsonTargetInfo, .jsonSwiftArtifacts,
9999
.indexUnitOutputPath, .modDepCache, .jsonAPIBaseline, .jsonABIBaseline,
100-
.swiftConstValues, nil:
100+
.swiftConstValues, .jsonAPIDescriptor, nil:
101101
return false
102102
}
103103
}
@@ -364,7 +364,6 @@ extension Driver {
364364
}
365365

366366
let expirementalFeatures = parsedOptions.arguments(for: .enableExperimentalFeature)
367-
let embeddedEnabled = expirementalFeatures.map(\.argument).map(\.asSingle).contains("Embedded")
368367

369368
try commandLine.appendLast(.trackSystemDependencies, from: &parsedOptions)
370369
try commandLine.appendLast(.CrossModuleOptimization, from: &parsedOptions)
@@ -467,7 +466,7 @@ extension FileType {
467466
.bitstreamOptimizationRecord, .swiftInterface, .privateSwiftInterface,
468467
.swiftSourceInfoFile, .clangModuleMap, .jsonSwiftArtifacts,
469468
.indexUnitOutputPath, .modDepCache, .jsonAPIBaseline, .jsonABIBaseline,
470-
.swiftConstValues:
469+
.swiftConstValues, .jsonAPIDescriptor:
471470
fatalError("Output type can never be a primary output")
472471
}
473472
}

Sources/SwiftDriver/Jobs/EmitModuleJob.swift

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extension Driver {
3434
addSupplementalOutput(path: swiftPrivateInterfacePath, flag: "-emit-private-module-interface-path", type: .privateSwiftInterface)
3535
addSupplementalOutput(path: objcGeneratedHeaderPath, flag: "-emit-objc-header-path", type: .objcHeader)
3636
addSupplementalOutput(path: tbdPath, flag: "-emit-tbd-path", type: .tbd)
37+
addSupplementalOutput(path: apiDescriptorFilePath, flag: "-emit-api-descriptor-path", type: .jsonAPIDescriptor)
3738

3839
if isMergeModule {
3940
return

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

+6
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,12 @@ extension Driver {
592592
input: nil,
593593
flag: "-emit-abi-descriptor-path")
594594
}
595+
596+
try addOutputOfType(
597+
outputType: .jsonAPIDescriptor,
598+
finalOutputPath: apiDescriptorFilePath,
599+
input: nil,
600+
flag: "-emit-api-descriptor-path")
595601
}
596602
}
597603

Sources/SwiftDriver/Utilities/FileType.swift

+13-3
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ public enum FileType: String, Hashable, CaseIterable, Codable {
151151

152152
/// ABI baseline JSON
153153
case jsonABIBaseline = "abi.json"
154+
155+
/// API descriptor JSON
156+
case jsonAPIDescriptor
154157
}
155158

156159
extension FileType: CustomStringConvertible {
@@ -235,6 +238,9 @@ extension FileType: CustomStringConvertible {
235238

236239
case .swiftConstValues:
237240
return "const-values"
241+
242+
case .jsonAPIDescriptor:
243+
return "api-descriptor-json"
238244
}
239245
}
240246
}
@@ -254,7 +260,7 @@ extension FileType {
254260
.swiftInterface, .privateSwiftInterface, .swiftSourceInfoFile,
255261
.jsonDependencies, .clangModuleMap, .jsonTargetInfo, .jsonCompilerFeatures,
256262
.jsonSwiftArtifacts, .indexUnitOutputPath, .modDepCache, .jsonAPIBaseline,
257-
.jsonABIBaseline, .swiftConstValues:
263+
.jsonABIBaseline, .swiftConstValues, .jsonAPIDescriptor:
258264
return false
259265
}
260266
}
@@ -359,6 +365,8 @@ extension FileType {
359365
return "abi-baseline-json"
360366
case .swiftConstValues:
361367
return "const-values"
368+
case .jsonAPIDescriptor:
369+
return "api-descriptor-json"
362370
}
363371
}
364372
}
@@ -370,7 +378,8 @@ extension FileType {
370378
.raw_sil, .llvmIR,.objcHeader, .autolink, .importedModules, .tbd,
371379
.moduleTrace, .yamlOptimizationRecord, .swiftInterface, .privateSwiftInterface,
372380
.jsonDependencies, .clangModuleMap, .jsonCompilerFeatures, .jsonTargetInfo,
373-
.jsonSwiftArtifacts, .jsonAPIBaseline, .jsonABIBaseline, .swiftConstValues:
381+
.jsonSwiftArtifacts, .jsonAPIBaseline, .jsonABIBaseline, .swiftConstValues,
382+
.jsonAPIDescriptor:
374383
return true
375384
case .image, .object, .dSYM, .pch, .sib, .raw_sib, .swiftModule,
376385
.swiftDocumentation, .swiftSourceInfoFile, .llvmBitcode, .diagnostics,
@@ -393,7 +402,8 @@ extension FileType {
393402
.importedModules, .tbd, .moduleTrace, .indexData, .yamlOptimizationRecord,
394403
.modDepCache, .bitstreamOptimizationRecord, .pcm, .pch, .jsonDependencies,
395404
.clangModuleMap, .jsonCompilerFeatures, .jsonTargetInfo, .jsonSwiftArtifacts,
396-
.indexUnitOutputPath, .jsonAPIBaseline, .jsonABIBaseline, .swiftConstValues:
405+
.indexUnitOutputPath, .jsonAPIBaseline, .jsonABIBaseline, .swiftConstValues,
406+
.jsonAPIDescriptor:
397407
return false
398408
}
399409
}

Sources/SwiftOptions/Options.swift

+2
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ extension Option {
273273
public static let embedBitcode: Option = Option("-embed-bitcode", .flag, attributes: [.frontend, .noInteractive], helpText: "Embed LLVM IR bitcode as data")
274274
public static let embedTbdForModule: Option = Option("-embed-tbd-for-module", .separate, attributes: [.frontend], helpText: "Embed symbols from the module in the emitted tbd file")
275275
public static let emitAbiDescriptorPath: Option = Option("-emit-abi-descriptor-path", .separate, attributes: [.frontend, .noDriver, .cacheInvariant], metaVar: "<path>", helpText: "Output the ABI descriptor of current module to <path>")
276+
public static let emitApiDescriptorPath: Option = Option("-emit-api-descriptor-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput, .cacheInvariant], metaVar: "<path>", helpText: "Output the API descriptor of current module to <path>")
276277
public static let emitAssembly: Option = Option("-emit-assembly", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild, .cacheInvariant], helpText: "Emit assembly file(s) (-S)", group: .modes)
277278
public static let emitAst: Option = Option("-emit-ast", .flag, alias: Option.dumpAst, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild])
278279
public static let emitBc: Option = Option("-emit-bc", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild, .cacheInvariant], helpText: "Emit LLVM BC file(s)", group: .modes)
@@ -1070,6 +1071,7 @@ extension Option {
10701071
Option.embedBitcode,
10711072
Option.embedTbdForModule,
10721073
Option.emitAbiDescriptorPath,
1074+
Option.emitApiDescriptorPath,
10731075
Option.emitAssembly,
10741076
Option.emitAst,
10751077
Option.emitBc,

Tests/SwiftDriverTests/SwiftDriverTests.swift

+44
Original file line numberDiff line numberDiff line change
@@ -7325,6 +7325,35 @@ final class SwiftDriverTests: XCTestCase {
73257325
let emitModuleJob = try XCTUnwrap(jobs.first(where: {$0.kind == .emitModule}))
73267326
XCTAssertTrue(emitModuleJob.commandLine.contains(.flag("-experimental-lazy-typecheck")))
73277327
}
7328+
7329+
func testEmitAPIDescriptorEmitModule() throws {
7330+
try withTemporaryDirectory { path in
7331+
let apiDescriptorPath = path.appending(component: "api.json").nativePathString(escaped: true)
7332+
var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift",
7333+
"-emit-module", "-module-name", "Test",
7334+
"-emit-api-descriptor-path", apiDescriptorPath])
7335+
7336+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
7337+
let emitModuleJob = try XCTUnwrap(jobs.first(where: {$0.kind == .emitModule}))
7338+
XCTAssert(emitModuleJob.commandLine.contains(.flag("-emit-api-descriptor-path")))
7339+
}
7340+
}
7341+
7342+
func testEmitAPIDescriptorWholeModuleOptimization() throws {
7343+
try withTemporaryDirectory { path in
7344+
let apiDescriptorPath = path.appending(component: "api.json").nativePathString(escaped: true)
7345+
var driver = try Driver(args: ["swiftc", "-whole-module-optimization",
7346+
"foo.swift", "bar.swift", "baz.swift",
7347+
"-module-name", "Test", "-emit-module",
7348+
"-emit-api-descriptor-path", apiDescriptorPath])
7349+
7350+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
7351+
let compileJob = try XCTUnwrap(jobs.first(where: {$0.kind == .compile}))
7352+
7353+
let supplementaryOutputs = try XCTUnwrap(compileJob.commandLine.supplementaryOutputFilemap)
7354+
XCTAssertNotNil(supplementaryOutputs.entries.values.first?[.jsonAPIDescriptor])
7355+
}
7356+
}
73287357
}
73297358

73307359
func assertString(
@@ -7394,4 +7423,19 @@ private extension Array where Element == Job.ArgTemplate {
73947423
}
73957424
}
73967425
}
7426+
7427+
var supplementaryOutputFilemap: OutputFileMap? {
7428+
get throws {
7429+
guard let argIdx = firstIndex(where: { $0 == .flag("-supplementary-output-file-map") }) else {
7430+
return nil
7431+
}
7432+
let supplementaryOutputs = self[argIdx + 1]
7433+
guard case let .path(path) = supplementaryOutputs,
7434+
case let .fileList(_, fileList) = path,
7435+
case let .outputFileMap(outputFileMap) = fileList else {
7436+
throw StringError("Unexpected argument for output file map")
7437+
}
7438+
return outputFileMap
7439+
}
7440+
}
73977441
}

0 commit comments

Comments
 (0)