Skip to content

Commit 881a358

Browse files
Merge pull request #1842 from cachemeifyoucan/eng/PR-enable-deterministic-check
Support driver flag `-enable-deterministic-check`
2 parents 6715b84 + f4be197 commit 881a358

File tree

4 files changed

+68
-2
lines changed

4 files changed

+68
-2
lines changed

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,15 @@ extension Driver {
505505
}
506506
}
507507

508+
if parsedOptions.contains(.enableDeterministicCheck),
509+
isFrontendArgSupported(.enableDeterministicCheck) {
510+
commandLine.appendFlag(.enableDeterministicCheck)
511+
commandLine.appendFlag(.alwaysCompileOutputFiles)
512+
if enableCaching {
513+
commandLine.appendFlag(.cacheDisableReplay)
514+
}
515+
}
516+
508517
// Pass along -no-verify-emitted-module-interface only if it's effective.
509518
// Assume verification by default as we want to know only when the user skips
510519
// the verification.

Sources/SwiftOptions/Options.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ extension Option {
431431
public static let enableDeserializationRecovery: Option = Option("-enable-deserialization-recovery", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Attempt to recover from missing xrefs (etc) in swiftmodules")
432432
public static let enableDeserializationSafety: Option = Option("-enable-deserialization-safety", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Avoid reading potentially unsafe decls in swiftmodules")
433433
public static let enableDestroyHoisting: Option = Option("-enable-destroy-hoisting=", .joined, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "true|false", helpText: "Whether to enable destroy hoisting")
434-
public static let enableDeterministicCheck: Option = Option("-enable-deterministic-check", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Check compiler output determinism by running it twice")
434+
public static let enableDeterministicCheck: Option = Option("-enable-deterministic-check", .flag, attributes: [.frontend, .doesNotAffectIncrementalBuild, .cacheInvariant], helpText: "Check compiler output determinism by running it twice")
435435
public static let enableDynamicReplacementChaining: Option = Option("-enable-dynamic-replacement-chaining", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable chaining of dynamic replacements")
436436
public static let enableEmitGenericClassRoTList: Option = Option("-enable-emit-generic-class-ro_t-list", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable emission of a section with references to class_ro_t of generic class patterns")
437437
public static let enableEmitTypeMallocForCoroFrame: Option = Option("-enable-emit-type-malloc-for-coro-frame", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable emitting typed malloc for coroutine frame allocation")
@@ -564,6 +564,7 @@ extension Option {
564564
public static let forcePublicLinkage: Option = Option("-force-public-linkage", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Force public linkage for private symbols. Used by LLDB.")
565565
public static let forceSingleFrontendInvocation: Option = Option("-force-single-frontend-invocation", .flag, alias: Option.wholeModuleOptimization, attributes: [.helpHidden, .frontend, .noInteractive])
566566
public static let forceStructTypeLayouts: Option = Option("-force-struct-type-layouts", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Force type layout based lowering for structs")
567+
public static let formalCxxInteroperabilityMode: Option = Option("-formal-cxx-interoperability-mode=", .joined, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "<cxx-interop-version>|off", helpText: "What version of C++ interoperability a textual interface was originally generated with")
567568
public static let framework: Option = Option("-framework", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Specifies a framework which should be linked against", group: .linkerOption)
568569
public static let frontendParseableOutput: Option = Option("-frontend-parseable-output", .flag, attributes: [.frontend, .noDriver, .cacheInvariant], helpText: "Emit textual output in a parseable format")
569570
public static let Fsystem: Option = Option("-Fsystem", .separate, attributes: [.frontend, .synthesizeInterface, .argumentIsPath], helpText: "Add directory to system framework search path")
@@ -848,7 +849,7 @@ extension Option {
848849
public static let staticExecutable: Option = Option("-static-executable", .flag, helpText: "Statically link the executable")
849850
public static let staticStdlib: Option = Option("-static-stdlib", .flag, attributes: [.doesNotAffectIncrementalBuild], helpText: "Statically link the Swift standard library")
850851
public static let `static`: Option = Option("-static", .flag, attributes: [.frontend, .noInteractive, .moduleInterface], helpText: "Make this module statically linkable and make the output of -emit-library a static library.")
851-
public static let statsOutputDir: Option = Option("-stats-output-dir", .separate, attributes: [.helpHidden, .frontend, .argumentIsPath], helpText: "Directory to write unified compilation-statistics files to")
852+
public static let statsOutputDir: Option = Option("-stats-output-dir", .separate, attributes: [.helpHidden, .frontend, .argumentIsPath, .cacheInvariant], helpText: "Directory to write unified compilation-statistics files to")
852853
public static let strictConcurrency: Option = Option("-strict-concurrency=", .joined, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Specify the how strict concurrency checking will be. The value may be 'minimal' (most 'Sendable' checking is disabled), 'targeted' ('Sendable' checking is enabled in code that uses the concurrency model, or 'complete' ('Sendable' and other checking is enabled for all code in the module)")
853854
public static let strictImplicitModuleContext: Option = Option("-strict-implicit-module-context", .flag, attributes: [.helpHidden, .frontend], helpText: "Enable the strict forwarding of compilation context to downstream implicit module dependencies")
854855
public static let strictMemorySafety: Option = Option("-strict-memory-safety", .flag, attributes: [.frontend, .synthesizeInterface], helpText: "Enable strict memory safety checking")
@@ -1508,6 +1509,7 @@ extension Option {
15081509
Option.forcePublicLinkage,
15091510
Option.forceSingleFrontendInvocation,
15101511
Option.forceStructTypeLayouts,
1512+
Option.formalCxxInteroperabilityMode,
15111513
Option.framework,
15121514
Option.frontendParseableOutput,
15131515
Option.Fsystem,

Tests/SwiftDriverTests/CachingBuildTests.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,50 @@ final class CachingBuildTests: XCTestCase {
10431043
}
10441044
}
10451045

1046+
func testDeterministicCheck() throws {
1047+
try withTemporaryDirectory { path in
1048+
try localFileSystem.changeCurrentWorkingDirectory(to: path)
1049+
let moduleCachePath = path.appending(component: "ModuleCache")
1050+
let casPath = path.appending(component: "cas")
1051+
try localFileSystem.createDirectory(moduleCachePath)
1052+
let main = path.appending(component: "testCachingBuild.swift")
1053+
let mainFileContent = "import C;"
1054+
try localFileSystem.writeFileContents(main) {
1055+
$0.send(mainFileContent)
1056+
}
1057+
let cHeadersPath: AbsolutePath =
1058+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
1059+
.appending(component: "CHeaders")
1060+
let swiftModuleInterfacesPath: AbsolutePath =
1061+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
1062+
.appending(component: "Swift")
1063+
let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? []
1064+
let bridgingHeaderpath: AbsolutePath =
1065+
cHeadersPath.appending(component: "Bridging.h")
1066+
var driver = try Driver(args: ["swiftc",
1067+
"-I", cHeadersPath.nativePathString(escaped: true),
1068+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
1069+
"-explicit-module-build", "-enable-deterministic-check",
1070+
"-module-cache-path", moduleCachePath.nativePathString(escaped: true),
1071+
"-cache-compile-job", "-cas-path", casPath.nativePathString(escaped: true),
1072+
"-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true),
1073+
"-working-directory", path.nativePathString(escaped: true),
1074+
main.nativePathString(escaped: true)] + sdkArgumentsForTesting,
1075+
interModuleDependencyOracle: dependencyOracle)
1076+
let jobs = try driver.planBuild()
1077+
jobs.forEach { job in
1078+
guard job.kind == .compile else {
1079+
return
1080+
}
1081+
XCTAssertJobInvocationMatches(job,
1082+
.flag("-enable-deterministic-check"),
1083+
.flag("-always-compile-output-files"),
1084+
.flag("-cache-disable-replay"))
1085+
}
1086+
}
1087+
1088+
}
1089+
10461090
func testCASManagement() throws {
10471091
try withTemporaryDirectory { path in
10481092
let casPath = path.appending(component: "cas")

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7086,6 +7086,17 @@ final class SwiftDriverTests: XCTestCase {
70867086
}
70877087
}
70887088

7089+
func testDeterministicCheck() throws {
7090+
do {
7091+
var driver = try Driver(args: ["swiftc", "-enable-deterministic-check", "foo.swift",
7092+
"-import-objc-header", "foo.h", "-enable-bridging-pch"])
7093+
let plannedJobs = try driver.planBuild()
7094+
// Check bridging header compilation command and main module command.
7095+
XCTAssertJobInvocationMatches(plannedJobs[0], .flag("-enable-deterministic-check"), .flag("-always-compile-output-files"))
7096+
XCTAssertJobInvocationMatches(plannedJobs[1], .flag("-enable-deterministic-check"), .flag("-always-compile-output-files"))
7097+
}
7098+
}
7099+
70897100
func testWarnConcurrency() throws {
70907101
do {
70917102
var driver = try Driver(args: ["swiftc", "-warn-concurrency", "foo.swift"])

0 commit comments

Comments
 (0)