Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit supplemental outputs for the target variant #1770

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
423 changes: 299 additions & 124 deletions Sources/SwiftDriver/Driver/Driver.swift

Large diffs are not rendered by default.

28 changes: 21 additions & 7 deletions Sources/SwiftDriver/Jobs/APIDigesterJobs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ extension Driver {
var commandLine = [Job.ArgTemplate]()
commandLine.appendFlag("-dump-sdk")

try addCommonDigesterOptions(&commandLine, modulePath: modulePath, mode: mode)
try addCommonDigesterOptions(&commandLine,
modulePath: modulePath,
swiftModuleInterfacePath: self.moduleOutputPaths.swiftInterfacePath,
mode: mode)

commandLine.appendFlag(.o)
commandLine.appendPath(VirtualPath.lookup(outputPath))
Expand All @@ -69,12 +72,16 @@ extension Driver {
case .api:
return nil
case .abi:
return abiDescriptorPath
return moduleOutputPaths.abiDescriptorFilePath
}
}
guard let currentABI = getDescriptorPath(for: mode) else {
// we don't have existing descriptor to use so we have to load the module from interface/swiftmodule
return try digesterCompareToBaselineJob(modulePath: modulePath, baselinePath: baselinePath, mode: digesterMode)
return try digesterCompareToBaselineJob(
modulePath: modulePath,
swiftModuleInterfacePath: self.moduleOutputPaths.swiftInterfacePath,
baselinePath: baselinePath,
mode: digesterMode)
}
var commandLine = [Job.ArgTemplate]()
commandLine.appendFlag("-diagnose-sdk")
Expand Down Expand Up @@ -105,14 +112,20 @@ extension Driver {
)
}

mutating func digesterCompareToBaselineJob(modulePath: VirtualPath.Handle, baselinePath: VirtualPath.Handle, mode: DigesterMode) throws -> Job {
mutating func digesterCompareToBaselineJob(modulePath: VirtualPath.Handle,
swiftModuleInterfacePath: VirtualPath.Handle?,
baselinePath: VirtualPath.Handle,
mode: DigesterMode) throws -> Job {
var commandLine = [Job.ArgTemplate]()
commandLine.appendFlag("-diagnose-sdk")
commandLine.appendFlag("-disable-fail-on-error")
commandLine.appendFlag("-baseline-path")
commandLine.appendPath(VirtualPath.lookup(baselinePath))

try addCommonDigesterOptions(&commandLine, modulePath: modulePath, mode: mode)
try addCommonDigesterOptions(&commandLine,
modulePath: modulePath,
swiftModuleInterfacePath: swiftModuleInterfacePath,
mode: mode)

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

Expand All @@ -147,6 +160,7 @@ extension Driver {

private mutating func addCommonDigesterOptions(_ commandLine: inout [Job.ArgTemplate],
modulePath: VirtualPath.Handle,
swiftModuleInterfacePath: VirtualPath.Handle?,
mode: DigesterMode) throws {
commandLine.appendFlag("-module")
commandLine.appendFlag(moduleOutputInfo.name)
Expand All @@ -160,7 +174,7 @@ extension Driver {
let searchPath = VirtualPath.lookup(modulePath).parentDirectory
commandLine.appendFlag(.I)
commandLine.appendPath(searchPath)
if let interfacePath = self.swiftInterfacePath {
if let interfacePath = swiftModuleInterfacePath {
let interfaceSearchPath = VirtualPath.lookup(interfacePath).parentDirectory
if interfaceSearchPath != searchPath {
commandLine.appendFlag(.I)
Expand Down
2 changes: 2 additions & 0 deletions Sources/SwiftDriver/Jobs/CompileJob.swift
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ extension Driver {
primaryInputs: primaryInputs,
inputsGeneratingCodeCount: inputsGeneratingCodeCount,
inputOutputMap: &inputOutputMap,
moduleOutputInfo: self.moduleOutputInfo,
moduleOutputPaths: self.moduleOutputPaths,
includeModuleTracePath: emitModuleTrace,
indexFilePath: indexFilePath)

Expand Down
31 changes: 21 additions & 10 deletions Sources/SwiftDriver/Jobs/EmitModuleJob.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ extension Driver {
mutating func addCommonModuleOptions(
commandLine: inout [Job.ArgTemplate],
outputs: inout [TypedVirtualPath],
moduleOutputPaths: SupplementalModuleTargetOutputPaths,
isMergeModule: Bool
) throws {
// Add supplemental outputs.
Expand All @@ -28,16 +29,16 @@ extension Driver {
outputs.append(.init(file: path, type: type))
}

addSupplementalOutput(path: moduleDocOutputPath, flag: "-emit-module-doc-path", type: .swiftDocumentation)
addSupplementalOutput(path: moduleSourceInfoPath, flag: "-emit-module-source-info-path", type: .swiftSourceInfoFile)
addSupplementalOutput(path: swiftInterfacePath, flag: "-emit-module-interface-path", type: .swiftInterface)
addSupplementalOutput(path: swiftPrivateInterfacePath, flag: "-emit-private-module-interface-path", type: .privateSwiftInterface)
addSupplementalOutput(path: moduleOutputPaths.moduleDocOutputPath, flag: "-emit-module-doc-path", type: .swiftDocumentation)
addSupplementalOutput(path: moduleOutputPaths.moduleSourceInfoPath, flag: "-emit-module-source-info-path", type: .swiftSourceInfoFile)
addSupplementalOutput(path: moduleOutputPaths.swiftInterfacePath, flag: "-emit-module-interface-path", type: .swiftInterface)
addSupplementalOutput(path: moduleOutputPaths.swiftPrivateInterfacePath, flag: "-emit-private-module-interface-path", type: .privateSwiftInterface)
if let pkgName = packageName, !pkgName.isEmpty {
addSupplementalOutput(path: swiftPackageInterfacePath, flag: "-emit-package-module-interface-path", type: .packageSwiftInterface)
addSupplementalOutput(path: moduleOutputPaths.swiftPackageInterfacePath, flag: "-emit-package-module-interface-path", type: .packageSwiftInterface)
}
addSupplementalOutput(path: objcGeneratedHeaderPath, flag: "-emit-objc-header-path", type: .objcHeader)
addSupplementalOutput(path: tbdPath, flag: "-emit-tbd-path", type: .tbd)
addSupplementalOutput(path: apiDescriptorFilePath, flag: "-emit-api-descriptor-path", type: .jsonAPIDescriptor)
addSupplementalOutput(path: moduleOutputPaths.apiDescriptorFilePath, flag: "-emit-api-descriptor-path", type: .jsonAPIDescriptor)

if isMergeModule {
return
Expand Down Expand Up @@ -78,8 +79,13 @@ extension Driver {
}

/// Form a job that emits a single module
@_spi(Testing) public mutating func emitModuleJob(pchCompileJob: Job?) throws -> Job {
let moduleOutputPath = moduleOutputInfo.output!.outputPath
@_spi(Testing) public mutating func emitModuleJob(pchCompileJob: Job?, isVariantJob: Bool = false) throws -> Job {
precondition(!isVariantJob || (isVariantJob &&
variantModuleOutputInfo != nil && variantModuleOutputPaths != nil),
"target variant module requested without a target variant")

let moduleOutputPath = isVariantJob ? variantModuleOutputInfo!.output!.outputPath : moduleOutputInfo.output!.outputPath
let moduleOutputPaths = isVariantJob ? variantModuleOutputPaths! : moduleOutputPaths
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
var inputs: [TypedVirtualPath] = []
var outputs: [TypedVirtualPath] = [
Expand All @@ -102,7 +108,12 @@ extension Driver {
try addCommonFrontendOptions(commandLine: &commandLine, inputs: &inputs, kind: .emitModule)
// FIXME: Add MSVC runtime library flags

try addCommonModuleOptions(commandLine: &commandLine, outputs: &outputs, isMergeModule: false)
try addCommonModuleOptions(
commandLine: &commandLine,
outputs: &outputs,
moduleOutputPaths: moduleOutputPaths,
isMergeModule: false)

try addCommonSymbolGraphOptions(commandLine: &commandLine)

try commandLine.appendLast(.checkApiAvailabilityOnly, from: &parsedOptions)
Expand All @@ -114,7 +125,7 @@ extension Driver {
let outputPath = VirtualPath.lookup(moduleOutputPath)
commandLine.appendFlag(.o)
commandLine.appendPath(outputPath)
if let abiPath = abiDescriptorPath {
if let abiPath = moduleOutputPaths.abiDescriptorFilePath {
commandLine.appendFlag(.emitAbiDescriptorPath)
commandLine.appendPath(abiPath.file)
outputs.append(abiPath)
Expand Down
28 changes: 18 additions & 10 deletions Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,8 @@ extension Driver {
primaryInputs: [TypedVirtualPath],
inputsGeneratingCodeCount: Int,
inputOutputMap: inout [TypedVirtualPath: [TypedVirtualPath]],
moduleOutputInfo: ModuleOutputInfo,
moduleOutputPaths: SupplementalModuleTargetOutputPaths,
includeModuleTracePath: Bool,
indexFilePath: TypedVirtualPath?) throws -> [TypedVirtualPath] {
var flaggedInputOutputPairs: [(flag: String, input: TypedVirtualPath?, output: TypedVirtualPath)] = []
Expand Down Expand Up @@ -592,7 +594,9 @@ extension Driver {
}

/// Add all of the outputs needed for a given input.
func addAllOutputsFor(input: TypedVirtualPath?) throws {
func addAllOutputsFor(input: TypedVirtualPath?,
moduleOutputInfo: ModuleOutputInfo,
moduleOutputPaths: SupplementalModuleTargetOutputPaths) throws {
if !emitModuleSeparately {
// Generate the module files with the main job.
try addOutputOfType(
Expand All @@ -602,12 +606,12 @@ extension Driver {
flag: "-emit-module-path")
try addOutputOfType(
outputType: .swiftDocumentation,
finalOutputPath: moduleDocOutputPath,
finalOutputPath: moduleOutputPaths.moduleDocOutputPath,
input: input,
flag: "-emit-module-doc-path")
try addOutputOfType(
outputType: .swiftSourceInfoFile,
finalOutputPath: moduleSourceInfoPath,
finalOutputPath: moduleOutputPaths.moduleSourceInfoPath,
input: input,
flag: "-emit-module-source-info-path")
}
Expand Down Expand Up @@ -645,10 +649,14 @@ extension Driver {

if compilerMode.usesPrimaryFileInputs {
for input in primaryInputs {
try addAllOutputsFor(input: input)
try addAllOutputsFor(input: input,
moduleOutputInfo: moduleOutputInfo,
moduleOutputPaths: moduleOutputPaths)
}
} else {
try addAllOutputsFor(input: nil)
try addAllOutputsFor(input: nil,
moduleOutputInfo: moduleOutputInfo,
moduleOutputPaths: moduleOutputPaths)

if !emitModuleSeparately {
// Outputs that only make sense when the whole module is processed
Expand All @@ -661,20 +669,20 @@ extension Driver {

try addOutputOfType(
outputType: .swiftInterface,
finalOutputPath: swiftInterfacePath,
finalOutputPath: moduleOutputPaths.swiftInterfacePath,
input: nil,
flag: "-emit-module-interface-path")

try addOutputOfType(
outputType: .privateSwiftInterface,
finalOutputPath: swiftPrivateInterfacePath,
finalOutputPath: moduleOutputPaths.swiftPrivateInterfacePath,
input: nil,
flag: "-emit-private-module-interface-path")

if let pkgName = packageName, !pkgName.isEmpty {
try addOutputOfType(
outputType: .packageSwiftInterface,
finalOutputPath: swiftPackageInterfacePath,
finalOutputPath: moduleOutputPaths.swiftPackageInterfacePath,
input: nil,
flag: "-emit-package-module-interface-path")
}
Expand All @@ -684,7 +692,7 @@ extension Driver {
input: nil,
flag: "-emit-tbd-path")

if let abiDescriptorPath = abiDescriptorPath {
if let abiDescriptorPath = moduleOutputPaths.abiDescriptorFilePath {
try addOutputOfType(outputType: .jsonABIBaseline,
finalOutputPath: abiDescriptorPath.fileHandle,
input: nil,
Expand All @@ -693,7 +701,7 @@ extension Driver {

try addOutputOfType(
outputType: .jsonAPIDescriptor,
finalOutputPath: apiDescriptorFilePath,
finalOutputPath: moduleOutputPaths.apiDescriptorFilePath,
input: nil,
flag: "-emit-api-descriptor-path")
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftDriver/Jobs/MergeModuleJob.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ extension Driver {
try addCommonFrontendOptions(commandLine: &commandLine, inputs: &inputs, kind: .mergeModule, bridgingHeaderHandling: .parsed)
// FIXME: Add MSVC runtime library flags

try addCommonModuleOptions(commandLine: &commandLine, outputs: &outputs, isMergeModule: true)
try addCommonModuleOptions(commandLine: &commandLine, outputs: &outputs, moduleOutputPaths: moduleOutputPaths, isMergeModule: true)

try addCommonSymbolGraphOptions(commandLine: &commandLine)

Expand All @@ -75,7 +75,7 @@ extension Driver {
commandLine.appendFlag(.o)
commandLine.appendPath(outputPath)

if let abiPath = abiDescriptorPath {
if let abiPath = moduleOutputPaths.abiDescriptorFilePath {
commandLine.appendFlag(.emitAbiDescriptorPath)
commandLine.appendPath(abiPath.file)
outputs.append(abiPath)
Expand Down
29 changes: 22 additions & 7 deletions Sources/SwiftDriver/Jobs/Planning.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,21 @@ extension Driver {
)
}

private mutating func addEmitModuleJob(addJobBeforeCompiles: (Job) -> Void, pchCompileJob: Job?) throws -> Job? {
if emitModuleSeparately {
let emitJob = try emitModuleJob(pchCompileJob: pchCompileJob)
addJobBeforeCompiles(emitJob)
return emitJob
}
return nil
private mutating func addEmitModuleJob(
addJobBeforeCompiles: (Job) -> Void,
pchCompileJob: Job?,
isVariantModule: Bool = false) throws -> Job? {
// The target variant module is always emitted separately, so we need to
// add an explicit job regardless of whether the primary target was
// emitted separately
if emitModuleSeparately || isVariantModule {
let emitJob = try emitModuleJob(
pchCompileJob: pchCompileJob,
isVariantJob: isVariantModule)
addJobBeforeCompiles(emitJob)
return emitJob
}
return nil
}

private mutating func addJobsFeedingLinker(
Expand Down Expand Up @@ -337,6 +345,13 @@ extension Driver {
addLinkerInput: addLinkerInput)
}

if variantModuleOutputInfo != nil {
_ = try addEmitModuleJob(
addJobBeforeCompiles: addJobBeforeCompiles,
pchCompileJob: jobCreatingPch,
isVariantModule: true)
}

try addJobsForPrimaryInputs(
addCompileJobGroup: addCompileJobGroup,
addModuleInput: addModuleInput,
Expand Down
16 changes: 16 additions & 0 deletions Sources/SwiftOptions/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,14 @@ extension Option {
public static let emitTbdPathEQ: Option = Option("-emit-tbd-path=", .joined, alias: Option.emitTbdPath, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput, .cacheInvariant])
public static let emitTbdPath: Option = Option("-emit-tbd-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput, .cacheInvariant], metaVar: "<path>", helpText: "Emit the TBD file to <path>")
public static let emitTbd: Option = Option("-emit-tbd", .flag, attributes: [.frontend, .noInteractive, .supplementaryOutput], helpText: "Emit a TBD file")
public static let emitVariantAbiDescriptorPath: Option = Option("-emit-variant-abi-descriptor-path", .separate, attributes: [.frontend, .noDriver, .cacheInvariant], metaVar: "<path>", helpText: "Output the ABI descriptor of current target variant module to <path>")
public static let emitVariantApiDescriptorPath: Option = Option("-emit-variant-api-descriptor-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput, .cacheInvariant], metaVar: "<path>", helpText: "Output a JSON file describing the target variant module's API to <path>")
public static let emitVariantModuleDocPath: Option = Option("-emit-variant-module-doc-path", .separate, attributes: [.frontend, .noDriver, .cacheInvariant], metaVar: "<path>", helpText: "Output module documentation file for the target variant to <path>")
public static let emitVariantModuleInterfacePath: Option = Option("-emit-variant-module-interface-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput, .cacheInvariant], metaVar: "<path>", helpText: "Output module interface file for the target variant to <path>")
public static let emitVariantModulePath: Option = Option("-emit-variant-module-path", .separate, attributes: [.noInteractive, .argumentIsPath, .supplementaryOutput, .cacheInvariant], metaVar: "<path>", helpText: "Emit an importable module for the target variant at the specified path")
public static let emitVariantModuleSourceInfoPath: Option = Option("-emit-variant-module-source-info-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput], metaVar: "<path>", helpText: "Output module source info file for the target variant to <path>")
public static let emitVariantPackageModuleInterfacePath: Option = Option("-emit-variant-package-module-interface-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput, .cacheInvariant], metaVar: "<path>", helpText: "Output package module interface file for the target variant to <path>")
public static let emitVariantPrivateModuleInterfacePath: Option = Option("-emit-variant-private-module-interface-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath, .supplementaryOutput, .cacheInvariant], metaVar: "<path>", helpText: "Output private module interface file for the target variant to <path>")
public static let emitVerboseSil: Option = Option("-emit-verbose-sil", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Emit locations during SIL emission")
public static let emptyAbiDescriptor: Option = Option("-empty-abi-descriptor", .flag, attributes: [.frontend, .noDriver], helpText: "Avoid printing actual module content into ABI descriptor file")
public static let emptyBaseline: Option = Option("-empty-baseline", .flag, attributes: [.noDriver], helpText: "Use empty baseline for diagnostics")
Expand Down Expand Up @@ -1294,6 +1302,14 @@ extension Option {
Option.emitTbdPathEQ,
Option.emitTbdPath,
Option.emitTbd,
Option.emitVariantAbiDescriptorPath,
Option.emitVariantApiDescriptorPath,
Option.emitVariantModuleDocPath,
Option.emitVariantModuleInterfacePath,
Option.emitVariantModulePath,
Option.emitVariantModuleSourceInfoPath,
Option.emitVariantPackageModuleInterfacePath,
Option.emitVariantPrivateModuleInterfacePath,
Option.emitVerboseSil,
Option.emptyAbiDescriptor,
Option.emptyBaseline,
Expand Down
Loading