Skip to content

[Explicit Module Builds] Cache explicit dependency additions to main module command-lines #1535

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 1 commit into from
Jan 30, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
/// Does this compile support `.explicitInterfaceModuleBuild`
private var supportsExplicitInterfaceBuild: Bool

/// Cached command-line additions for all main module compile jobs
private struct ResolvedModuleDependenciesCommandLineComponents {
let inputs: [TypedVirtualPath]
let commandLine: [Job.ArgTemplate]
}
private var resolvedMainModuleDependenciesArgs: ResolvedModuleDependenciesCommandLineComponents? = nil

public init(dependencyGraph: InterModuleDependencyGraph,
toolchain: Toolchain,
dependencyOracle: InterModuleDependencyOracle,
Expand Down Expand Up @@ -396,18 +403,31 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
/// inputs and command line flags.
public mutating func resolveMainModuleDependencies(inputs: inout [TypedVirtualPath],
commandLine: inout [Job.ArgTemplate]) throws {
let mainModuleId: ModuleDependencyId = .swift(dependencyGraph.mainModuleName)

let mainModuleDetails = try dependencyGraph.swiftModuleDetails(of: mainModuleId)
if let additionalArgs = mainModuleDetails.commandLine {
additionalArgs.forEach { commandLine.appendFlag($0) }
// If not previously computed, gather all dependency input files and command-line arguments
if resolvedMainModuleDependenciesArgs == nil {
var inputAdditions: [TypedVirtualPath] = []
var commandLineAdditions: [Job.ArgTemplate] = []
let mainModuleId: ModuleDependencyId = .swift(dependencyGraph.mainModuleName)
let mainModuleDetails = try dependencyGraph.swiftModuleDetails(of: mainModuleId)
if let additionalArgs = mainModuleDetails.commandLine {
additionalArgs.forEach { commandLine.appendFlag($0) }
}
commandLineAdditions.appendFlags("-disable-implicit-swift-modules",
"-Xcc", "-fno-implicit-modules",
"-Xcc", "-fno-implicit-module-maps")
try resolveExplicitModuleDependencies(moduleId: mainModuleId,
inputs: &inputAdditions,
commandLine: &commandLineAdditions)
resolvedMainModuleDependenciesArgs = ResolvedModuleDependenciesCommandLineComponents(
inputs: inputAdditions,
commandLine: commandLineAdditions
)
}
commandLine.appendFlags("-disable-implicit-swift-modules",
"-Xcc", "-fno-implicit-modules",
"-Xcc", "-fno-implicit-module-maps")
try resolveExplicitModuleDependencies(moduleId: mainModuleId,
inputs: &inputs,
commandLine: &commandLine)
guard let mainModuleDependenciesArgs = resolvedMainModuleDependenciesArgs else {
fatalError("Failed to compute resolved explicit dependency arguments.")
}
inputs.append(contentsOf: mainModuleDependenciesArgs.inputs)
commandLine.append(contentsOf: mainModuleDependenciesArgs.commandLine)
}

/// Resolve all module dependencies of the main module and add them to the lists of
Expand Down
23 changes: 7 additions & 16 deletions Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -736,30 +736,21 @@ extension Driver {

/// Adds all dependencies required for an explicit module build
/// to inputs and command line arguments of a compile job.
func addExplicitModuleBuildArguments(inputs: inout [TypedVirtualPath],
commandLine: inout [Job.ArgTemplate]) throws {
guard var dependencyPlanner = explicitDependencyBuildPlanner else {
fatalError("No dependency planner in Explicit Module Build mode.")
}
try dependencyPlanner.resolveMainModuleDependencies(inputs: &inputs, commandLine: &commandLine)
mutating func addExplicitModuleBuildArguments(inputs: inout [TypedVirtualPath],
commandLine: inout [Job.ArgTemplate]) throws {
try explicitDependencyBuildPlanner?.resolveMainModuleDependencies(inputs: &inputs, commandLine: &commandLine)
}

/// Adds all dependencies required for an explicit module build of the bridging header
/// to inputs and command line arguments of a compile job.
func addExplicitPCHBuildArguments(inputs: inout [TypedVirtualPath],
commandLine: inout [Job.ArgTemplate]) throws {
guard var dependencyPlanner = explicitDependencyBuildPlanner else {
fatalError("No dependency planner in Explicit Module Build mode.")
}
try dependencyPlanner.resolveBridgingHeaderDependencies(inputs: &inputs, commandLine: &commandLine)
mutating func addExplicitPCHBuildArguments(inputs: inout [TypedVirtualPath],
commandLine: inout [Job.ArgTemplate]) throws {
try explicitDependencyBuildPlanner?.resolveBridgingHeaderDependencies(inputs: &inputs, commandLine: &commandLine)
}

/// If explicit dependency planner supports creating bridging header pch command.
public func supportsBridgingHeaderPCHCommand() throws -> Bool {
guard let dependencyPlanner = explicitDependencyBuildPlanner else {
return false
}
return try dependencyPlanner.supportsBridgingHeaderPCHCommand()
return try explicitDependencyBuildPlanner?.supportsBridgingHeaderPCHCommand() ?? false
}

/// In Explicit Module Build mode, distinguish between main module jobs and intermediate dependency build jobs,
Expand Down
49 changes: 49 additions & 0 deletions Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,55 @@ final class ExplicitModuleBuildTests: XCTestCase {
}
}

func testModuleDependencyBuildCommandUniqueDepFile() throws {
try withTemporaryDirectory { path in
let source0 = path.appending(component: "testModuleDependencyBuildCommandUniqueDepFile1.swift")
let source1 = path.appending(component: "testModuleDependencyBuildCommandUniqueDepFile2.swift")
try localFileSystem.writeFileContents(source0, bytes:
"""
import C;
"""
)
try localFileSystem.writeFileContents(source1, bytes:
"""
import G;
"""
)

let cHeadersPath: AbsolutePath =
try testInputsPath.appending(component: "ExplicitModuleBuilds")
.appending(component: "CHeaders")
let bridgingHeaderpath: AbsolutePath =
cHeadersPath.appending(component: "Bridging.h")
let swiftModuleInterfacesPath: AbsolutePath =
try testInputsPath.appending(component: "ExplicitModuleBuilds")
.appending(component: "Swift")
let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? []
var driver = try Driver(args: ["swiftc",
"-target", "x86_64-apple-macosx11.0",
"-I", cHeadersPath.nativePathString(escaped: true),
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
"-explicit-module-build",
"-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true),
source0.nativePathString(escaped: true),
source1.nativePathString(escaped: true)] + sdkArgumentsForTesting)

let jobs = try driver.planBuild()
let compileJobs = jobs.filter({ $0.kind == .compile })
XCTAssertEqual(compileJobs.count, 2)
let compileJob0 = compileJobs[0]
let compileJob1 = compileJobs[1]
let explicitDepsFlag = SwiftDriver.Job.ArgTemplate.flag(String("-explicit-swift-module-map-file"))
XCTAssert(compileJob0.commandLine.contains(explicitDepsFlag))
XCTAssert(compileJob1.commandLine.contains(explicitDepsFlag))
let jsonDeps0PathIndex = compileJob0.commandLine.firstIndex(of: explicitDepsFlag)
let jsonDeps0PathArg = compileJob0.commandLine[jsonDeps0PathIndex! + 1]
let jsonDeps1PathIndex = compileJob1.commandLine.firstIndex(of: explicitDepsFlag)
let jsonDeps1PathArg = compileJob1.commandLine[jsonDeps1PathIndex! + 1]
XCTAssertEqual(jsonDeps0PathArg, jsonDeps1PathArg)
}
}

private func pathMatchesSwiftModule(path: VirtualPath, _ name: String) -> Bool {
return path.basenameWithoutExt.starts(with: "\(name)-") &&
path.extension! == FileType.swiftModule.rawValue
Expand Down