Skip to content

[Caching] Remap block-list files if needed #1858

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
Apr 1, 2025
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
20 changes: 14 additions & 6 deletions Sources/SwiftDriver/Driver/Driver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ public struct Driver {
/// Code & data for incremental compilation. Nil if not running in incremental mode.
/// Set during planning because needs the jobs to look at outputs.
@_spi(Testing) public private(set) var incrementalCompilationState: IncrementalCompilationState? = nil

/// The graph of explicit module dependencies of this module, if the driver has planned an explicit module build.
public private(set) var intermoduleDependencyGraph: InterModuleDependencyGraph? = nil

Expand Down Expand Up @@ -703,6 +703,14 @@ public struct Driver {
return try toolchain.lookupSwiftScanLib()
}

func findBlocklists() throws -> [AbsolutePath] {
if let mockBlocklistDir = env["_SWIFT_DRIVER_MOCK_BLOCK_LIST_DIR"] {
// Use testing block-list directory.
return try Driver.findBlocklists(RelativeTo: try AbsolutePath(validating: mockBlocklistDir))
}
return try Driver.findBlocklists(RelativeTo: try toolchain.executableDir)
}

@_spi(Testing)
public static func findBlocklists(RelativeTo execDir: AbsolutePath) throws -> [AbsolutePath] {
// Expect to find all blocklists in such dir:
Expand Down Expand Up @@ -890,7 +898,7 @@ public struct Driver {
let cwd = fileSystem.currentWorkingDirectory
return try cwd.map{ try AbsolutePath(validating: workingDirectoryArg.asSingle, relativeTo: $0) } ?? AbsolutePath(validating: workingDirectoryArg.asSingle)
}

if let specifiedWorkingDir = self.workingDirectory {
// Apply the working directory to the parsed options if passed explicitly.
try Self.applyWorkingDirectory(specifiedWorkingDir, to: &self.parsedOptions)
Expand Down Expand Up @@ -987,8 +995,8 @@ public struct Driver {

self.lto = Self.ltoKind(&parsedOptions, diagnosticsEngine: diagnosticsEngine)
// Figure out the primary outputs from the driver.
(self.compilerOutputType, self.linkerOutputType) =
Self.determinePrimaryOutputs(&parsedOptions, targetTriple: self.frontendTargetInfo.target.triple,
(self.compilerOutputType, self.linkerOutputType) =
Self.determinePrimaryOutputs(&parsedOptions, targetTriple: self.frontendTargetInfo.target.triple,
driverKind: driverKind, diagnosticsEngine: diagnosticEngine)

// Multithreading.
Expand Down Expand Up @@ -1980,12 +1988,12 @@ extension Driver {
guard let buildRecordInfo = self.buildRecordInfo, let incrementalCompilationState = self.incrementalCompilationState else {
return
}

let buildRecord = buildRecordInfo.buildRecord(
jobs, self.incrementalCompilationState?.blockingConcurrentMutationToProtectedState{
$0.skippedCompilationInputs
})

do {
try incrementalCompilationState.writeDependencyGraph(to: buildRecordInfo.dependencyGraphPath, buildRecord)
} catch {
Expand Down
29 changes: 17 additions & 12 deletions Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,10 @@ extension Driver {
}
}

try commandLine.appendAll(.I, from: &parsedOptions)
try commandLine.appendAll(.F, .Fsystem, from: &parsedOptions)
try commandLine.appendAll(.vfsoverlay, from: &parsedOptions)
// TODO: Can we drop all search paths for compile jobs for explicit module build?
try addAllArgumentsWithPath(.I, to: &commandLine, remap: jobNeedPathRemap)
try addAllArgumentsWithPath(.F, .Fsystem, to: &commandLine, remap: jobNeedPathRemap)
try addAllArgumentsWithPath(.vfsoverlay, to: &commandLine, remap: jobNeedPathRemap)

if let gccToolchain = parsedOptions.getLastArgument(.gccToolchain) {
appendXccFlag("--gcc-toolchain=\(gccToolchain.asSingle)")
Expand Down Expand Up @@ -247,8 +248,8 @@ extension Driver {
commandLine.appendFlag("-sample-profile-use-profi")
}
try commandLine.appendAllExcept(
includeList: [.warningTreating],
excludeList: [],
includeList: [.warningTreating],
excludeList: [],
from: &parsedOptions
)
try commandLine.appendLast(.sanitizeEQ, from: &parsedOptions)
Expand Down Expand Up @@ -350,9 +351,9 @@ extension Driver {
}

if isFrontendArgSupported(.blockListFile) {
try Driver.findBlocklists(RelativeTo: try toolchain.executableDir).forEach {
try findBlocklists().forEach {
commandLine.appendFlag(.blockListFile)
commandLine.appendPath($0)
try addPathArgument(VirtualPath.absolute($0), to: &commandLine)
}
}

Expand Down Expand Up @@ -1012,15 +1013,20 @@ extension Driver {
}

public mutating func addPathOption(option: Option, path: VirtualPath, to commandLine: inout [Job.ArgTemplate], remap: Bool = true) throws {
commandLine.appendFlag(option)
let needRemap = remap && option.attributes.contains(.argumentIsPath) &&
let needRemap = remap && isCachingEnabled && option.attributes.contains(.argumentIsPath) &&
!option.attributes.contains(.cacheInvariant)
try addPathArgument(path, to: &commandLine, remap: needRemap)
let commandPath = needRemap ? remapPath(path) : path
if option.kind == .joined {
commandLine.append(.joinedOptionAndPath(option.spelling, commandPath))
} else {
// All other kinds that involves a path can be added as separated args.
commandLine.appendFlag(option)
commandLine.appendPath(commandPath)
}
}

/// Helper function to add last argument with path to command-line.
public mutating func addLastArgumentWithPath(_ options: Option...,
from parsedOptions: inout ParsedOptions,
to commandLine: inout [Job.ArgTemplate],
remap: Bool = true) throws {
guard let parsedOption = parsedOptions.last(for: options) else {
Expand All @@ -1031,7 +1037,6 @@ extension Driver {

/// Helper function to add all arguments with path to command-line.
public mutating func addAllArgumentsWithPath(_ options: Option...,
from parsedOptions: inout ParsedOptions,
to commandLine: inout [Job.ArgTemplate],
remap: Bool) throws {
for matching in parsedOptions.arguments(for: options) {
Expand Down
10 changes: 9 additions & 1 deletion Tests/SwiftDriverTests/CachingBuildTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,9 @@ final class CachingBuildTests: XCTestCase {
.appending(component: "Swift")
let casPath = path.appending(component: "cas")
let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? []
let mockBlocklistDir = try testInputsPath.appending(components: "Dummy.xctoolchain", "usr", "bin")
var env = ProcessEnv.vars
env["_SWIFT_DRIVER_MOCK_BLOCK_LIST_DIR"] = mockBlocklistDir.nativePathString(escaped: true)
var driver = try Driver(args: ["swiftc",
"-I", cHeadersPath.nativePathString(escaped: true),
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
Expand All @@ -907,6 +910,7 @@ final class CachingBuildTests: XCTestCase {
"-scanner-prefix-map", testInputsPath.description + "=/^src",
"-scanner-prefix-map", path.description + "=/^tmp",
main.nativePathString(escaped: true)] + sdkArgumentsForTesting,
env: env,
interModuleDependencyOracle: dependencyOracle)
guard driver.isFrontendArgSupported(.scannerPrefixMap) else {
throw XCTSkip("frontend doesn't support prefix map")
Expand All @@ -929,7 +933,11 @@ final class CachingBuildTests: XCTestCase {
// The only one that is not remapped should be the `-cas-path` that points to
// `casPath`.
XCTAssertFalse(command.contains {
return $0.starts(with: path.description) && $0 != casPath.description
$0.starts(with: path.description) && $0 != casPath.description
})
/// All source location path should be remapped as well.
XCTAssertFalse(try command.contains {
$0.starts(with: try testInputsPath.description)
})
}
}
Expand Down