Skip to content

[5.5] Bug fixes and test updates for emit-module-separately #849

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

Merged
merged 8 commits into from
Sep 23, 2021
12 changes: 10 additions & 2 deletions Sources/SwiftDriver/Jobs/EmitModuleJob.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,15 @@ extension Driver {
addSupplementalOutput(path: objcGeneratedHeaderPath, flag: "-emit-objc-header-path", type: .objcHeader)
addSupplementalOutput(path: tbdPath, flag: "-emit-tbd-path", type: .tbd)

if isMergeModule || shouldCreateEmitModuleJob {
if isMergeModule {
return
}

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

// Add outputs that can't be merged
addSupplementalOutput(path: serializedDiagnosticsFilePath, flag: "-serialize-diagnostics-path", type: .diagnostics)
if let dependenciesFilePath = dependenciesFilePath {
Expand Down Expand Up @@ -103,7 +109,9 @@ extension Driver {

/// Returns true if the -emit-module-separately is active.
mutating func shouldEmitModuleSeparately() -> Bool {
return parsedOptions.hasArgument(.emitModuleSeparately)
return parsedOptions.hasFlag(positive: .emitModuleSeparately,
negative: .noEmitModuleSeparately,
default: false)
&& !parsedOptions.hasFlag(positive: .wholeModuleOptimization,
negative: .noWholeModuleOptimization,
default: false)
Expand Down
37 changes: 31 additions & 6 deletions Sources/SwiftDriver/Jobs/Planning.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ extension Driver {

try addPrecompileModuleDependenciesJobs(addJob: addJobBeforeCompiles)
try addPrecompileBridgingHeaderJob(addJob: addJobBeforeCompiles)
try addEmitModuleJob(addJobBeforeCompiles: addJobBeforeCompiles, addJobAfterCompiles: addJobAfterCompiles)
let linkerInputs = try addJobsFeedingLinker(
addJobBeforeCompiles: addJobBeforeCompiles,
addCompileJobGroup: addCompileJobGroup,
Expand Down Expand Up @@ -179,12 +178,13 @@ extension Driver {
)
}

private mutating func addEmitModuleJob(addJobBeforeCompiles: (Job) -> Void, addJobAfterCompiles: (Job) -> Void) throws {
private mutating func addEmitModuleJob(addJobBeforeCompiles: (Job) -> Void) throws -> Job? {
if shouldCreateEmitModuleJob {
let emitJob = try emitModuleJob()
addJobBeforeCompiles(emitJob)
try addVerifyJobs(emitModuleJob: emitJob, addJob: addJobAfterCompiles)
return emitJob
}
return nil
}

private mutating func addJobsFeedingLinker(
Expand Down Expand Up @@ -219,10 +219,32 @@ extension Driver {
}
}

// Ensure that only one job emits the module files and insert a verify swiftinterface job
var jobCreatingSwiftModule: Job? = nil
func addPostModuleFilesJobs(_ emitModuleJob: Job) throws {
// We should only emit module files from one job
assert(jobCreatingSwiftModule == nil)
jobCreatingSwiftModule = emitModuleJob

try addVerifyJobs(emitModuleJob: emitModuleJob, addJob: addJobAfterCompiles)
}

// Whole-module
if let compileJob = try addSingleCompileJobs(addJob: addJobBeforeCompiles,
addJobOutputs: addJobOutputs,
emitModuleTrace: loadedModuleTracePath != nil) {
try addVerifyJobs(emitModuleJob: compileJob, addJob: addJobAfterCompiles)
try addPostModuleFilesJobs(compileJob)
}

// Emit-module-separately
if let emitModuleJob = try addEmitModuleJob(addJobBeforeCompiles: addJobBeforeCompiles) {
try addPostModuleFilesJobs(emitModuleJob)

try addWrapJobOrMergeOutputs(
mergeJob: emitModuleJob,
debugInfo: debugInfo,
addJob: addJobAfterCompiles,
addLinkerInput: addLinkerInput)
}

try addJobsForPrimaryInputs(
Expand All @@ -235,11 +257,13 @@ extension Driver {
addLinkerInput: addLinkerInput,
addJob: addJobAfterCompiles)

// Merge-module
if let mergeJob = try mergeModuleJob(
moduleInputs: moduleInputs,
moduleInputsFromJobOutputs: moduleInputsFromJobOutputs) {
addJobAfterCompiles(mergeJob)
try addVerifyJobs(emitModuleJob: mergeJob, addJob: addJobAfterCompiles)
try addPostModuleFilesJobs(mergeJob)

try addWrapJobOrMergeOutputs(
mergeJob: mergeJob,
debugInfo: debugInfo,
Expand Down Expand Up @@ -394,7 +418,8 @@ extension Driver {
) throws -> Job? {
guard moduleOutputInfo.output != nil,
!(moduleInputs.isEmpty && moduleInputsFromJobOutputs.isEmpty),
compilerMode.usesPrimaryFileInputs
compilerMode.usesPrimaryFileInputs,
!shouldCreateEmitModuleJob
else { return nil }
return try mergeModuleJob(inputs: moduleInputs, inputsFromOutputs: moduleInputsFromJobOutputs)
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/SwiftOptions/ExtraOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ extension Option {
public static let driverScanDependenciesNonLib: Option = Option("-nonlib-dependency-scanner", .flag, attributes: [.helpHidden], helpText: "Use calls to `swift-frontend -scan-dependencies` instead of dedicated dependency scanning library")
public static let driverWarnUnusedOptions: Option = Option("-driver-warn-unused-options", .flag, attributes: [.helpHidden], helpText: "Emit warnings for any provided options which are unused by the driver")
public static let emitModuleSeparately: Option = Option("-experimental-emit-module-separately", .flag, attributes: [.helpHidden], helpText: "Emit module files as a distinct job")
public static let noEmitModuleSeparately: Option = Option("-no-emit-module-separately", .flag, attributes: [.helpHidden], helpText: "Force using merge-module as the incremental build mode")
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")

// API digester operations
Expand All @@ -32,6 +33,7 @@ extension Option {
Option.driverScanDependenciesNonLib,
Option.driverWarnUnusedOptions,
Option.emitModuleSeparately,
Option.noEmitModuleSeparately,
Option.useFrontendParseableOutput,
Option.emitDigesterBaseline,
Option.emitDigesterBaselinePath,
Expand Down
6 changes: 3 additions & 3 deletions Tests/SwiftDriverTests/ParsableMessageTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ final class ParsableMessageTests: XCTestCase {
try withTemporaryDirectory { path in
try withHijackedBufferedErrorStream(in: path) { errorBuffer in
let resolver = try ArgsResolver(fileSystem: localFileSystem)
var driver = try Driver(args: ["swiftc", "-emit-module", "-o", "test.swiftmodule",
var driver = try Driver(args: ["swiftc", "-o", "test.o",
"main.swift", "test1.swift", "test2.swift",
"-enable-batch-mode", "-driver-batch-count", "1",
"-working-directory", "/WorkDir"])
Expand Down Expand Up @@ -201,7 +201,7 @@ final class ParsableMessageTests: XCTestCase {
var toolDelegate: ToolExecutionDelegate?
try withHijackedBufferedErrorStream(in: path) { errorBuffer in
let resolver = try ArgsResolver(fileSystem: localFileSystem)
var driver = try Driver(args: ["swiftc", "-emit-module", "-o", "test.swiftmodule",
var driver = try Driver(args: ["swiftc", "-o", "test.o",
"main.swift", "test1.swift", "test2.swift",
"-enable-batch-mode", "-driver-batch-count", "1",
"-working-directory", "/WorkDir"])
Expand Down Expand Up @@ -278,7 +278,7 @@ final class ParsableMessageTests: XCTestCase {
var toolDelegate: ToolExecutionDelegate?
try withHijackedBufferedErrorStream(in: path) { errorBuffer in
let resolver = try ArgsResolver(fileSystem: localFileSystem)
var driver = try Driver(args: ["swiftc", "-emit-module", "-o", "test.swiftmodule",
var driver = try Driver(args: ["swiftc", "-o", "test.o",
"main.swift", "test1.swift", "test2.swift",
"-enable-batch-mode", "-driver-batch-count", "1",
"-working-directory", "/WorkDir"])
Expand Down
Loading