Skip to content

Extract everything depending on LLBuild into a SwiftDriverExecution library #263

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
Sep 24, 2020
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
16 changes: 13 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,25 @@ let package = Package(
.library(
name: "SwiftOptions",
targets: ["SwiftOptions"]),
.library(
name: "SwiftDriverExecution",
targets: ["SwiftDriverExecution"]),
],
targets: [
/// The driver library.
.target(
name: "SwiftDriver",
dependencies: ["SwiftOptions", "SwiftToolsSupport-auto", "Yams"]),

/// The execution library.
.target(
name: "SwiftDriverExecution",
dependencies: ["SwiftDriver", "SwiftToolsSupport-auto"]),

/// Driver tests.
.testTarget(
name: "SwiftDriverTests",
dependencies: ["SwiftDriver", "swift-driver"]),
dependencies: ["SwiftDriver", "SwiftDriverExecution", "swift-driver"]),

/// The options library.
.target(
Expand All @@ -48,7 +58,7 @@ let package = Package(
/// The primary driver executable.
.target(
name: "swift-driver",
dependencies: ["SwiftDriver"]),
dependencies: ["SwiftDriverExecution", "SwiftDriver"]),

/// The help executable.
.target(
Expand All @@ -75,7 +85,7 @@ if ProcessInfo.processInfo.environment["SWIFT_DRIVER_LLBUILD_FWK"] == nil {
.package(path: "../llbuild"),
]
}
package.targets.first(where: { $0.name == "SwiftDriver" })!.dependencies += ["llbuildSwift"]
package.targets.first(where: { $0.name == "SwiftDriverExecution" })!.dependencies += ["llbuildSwift"]
}

if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
Expand Down
1 change: 1 addition & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@

add_subdirectory(SwiftOptions)
add_subdirectory(SwiftDriver)
add_subdirectory(SwiftDriverExecution)
add_subdirectory(swift-driver)
add_subdirectory(swift-help)
5 changes: 1 addition & 4 deletions Sources/SwiftDriver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ add_library(SwiftDriver
Driver/ToolExecutionDelegate.swift

Execution/ArgsResolver.swift
Execution/MultiJobExecutor.swift
Execution/DriverExecutor.swift
Execution/ParsableOutput.swift
Execution/ProcessProtocol.swift
Execution/llbuild.swift

"Incremental Compilation/IncrementalCompilationState.swift"
"Incremental Compilation/InputIInfoMap.swift"
Expand Down Expand Up @@ -84,8 +82,7 @@ add_library(SwiftDriver
target_link_libraries(SwiftDriver PUBLIC
TSCBasic
TSCUtility
SwiftOptions
llbuildSwift)
SwiftOptions)
target_link_libraries(SwiftDriver PRIVATE
CYaml
Yams)
Expand Down
2 changes: 0 additions & 2 deletions Sources/SwiftDriver/Driver/OutputFileMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
import TSCBasic
import Foundation

public typealias FileSystem = TSCBasic.FileSystem

/// Mapping of input file paths to specific output files.
public struct OutputFileMap: Hashable, Codable {
static let singleInputKey = VirtualPath.relative(RelativePath(""))
Expand Down
84 changes: 0 additions & 84 deletions Sources/SwiftDriver/Execution/DriverExecutor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,87 +91,3 @@ public protocol JobExecutionDelegate {
/// Called when a job finished.
func jobFinished(job: Job, result: ProcessResult, pid: Int)
}

public final class SwiftDriverExecutor: DriverExecutor {
let diagnosticsEngine: DiagnosticsEngine
let processSet: ProcessSet
let fileSystem: FileSystem
public let resolver: ArgsResolver
let env: [String: String]

public init(diagnosticsEngine: DiagnosticsEngine,
processSet: ProcessSet,
fileSystem: FileSystem,
env: [String: String]) throws {
self.diagnosticsEngine = diagnosticsEngine
self.processSet = processSet
self.fileSystem = fileSystem
self.env = env
self.resolver = try ArgsResolver(fileSystem: fileSystem)
}

public func execute(job: Job,
forceResponseFiles: Bool = false,
recordedInputModificationDates: [TypedVirtualPath: Date] = [:]) throws -> ProcessResult {
let arguments: [String] = try resolver.resolveArgumentList(for: job,
forceResponseFiles: forceResponseFiles)

try job.verifyInputsNotModified(since: recordedInputModificationDates,
fileSystem: fileSystem)

if job.requiresInPlaceExecution {
for (envVar, value) in job.extraEnvironment {
try ProcessEnv.setVar(envVar, value: value)
}

try exec(path: arguments[0], args: arguments)
fatalError("unreachable, exec always throws on failure")
} else {
var childEnv = env
childEnv.merge(job.extraEnvironment, uniquingKeysWith: { (_, new) in new })

let process = try Process.launchProcess(arguments: arguments, env: childEnv)
return try process.waitUntilExit()
}
}

public func execute(jobs: [Job],
delegate: JobExecutionDelegate,
numParallelJobs: Int = 1,
forceResponseFiles: Bool = false,
recordedInputModificationDates: [TypedVirtualPath: Date] = [:]
) throws {
let llbuildExecutor = MultiJobExecutor(jobs: jobs,
resolver: resolver,
executorDelegate: delegate,
diagnosticsEngine: diagnosticsEngine,
numParallelJobs: numParallelJobs,
processSet: processSet,
forceResponseFiles: forceResponseFiles,
recordedInputModificationDates: recordedInputModificationDates)
try llbuildExecutor.execute(env: env, fileSystem: fileSystem)
}

@discardableResult
public func checkNonZeroExit(args: String..., environment: [String: String] = ProcessEnv.vars) throws -> String {
return try Process.checkNonZeroExit(arguments: args, environment: environment)
}

public func description(of job: Job, forceResponseFiles: Bool) throws -> String {
let (args, usedResponseFile) = try resolver.resolveArgumentList(for: job, forceResponseFiles: forceResponseFiles)
var result = args.joined(separator: " ")

if usedResponseFile {
// Print the response file arguments as a comment.
result += " # \(job.commandLine.joinedArguments)"
}

if !job.extraEnvironment.isEmpty {
result += " #"
for (envVar, val) in job.extraEnvironment {
result += " \(envVar)=\(val)"
}
}
return result
}
}
Loading