Skip to content

Commit d87a2d8

Browse files
committed
Isolate ModuleCache for SwiftPM tests
To workaround the ModuleCache issues that we've been seeing on Swift CI <rdar://problem/51596389>
1 parent e6b75cb commit d87a2d8

File tree

4 files changed

+19
-17
lines changed

4 files changed

+19
-17
lines changed

Sources/Build/BuildPlan.swift

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,14 @@ public struct BuildParameters {
2626
case auto
2727
}
2828

29-
// FIXME: Error handling.
30-
//
31-
/// Path to the module cache directory to use for SwiftPM's own tests.
32-
public static let swiftpmTestCache = resolveSymlinks(try! determineTempDirectory()).appending(component: "org.swift.swiftpm.tests-3")
33-
3429
/// Returns the directory to be used for module cache.
3530
fileprivate var moduleCache: AbsolutePath {
36-
let base: AbsolutePath
3731
// FIXME: We use this hack to let swiftpm's functional test use shared
3832
// cache so it doesn't become painfully slow.
39-
if Process.env["IS_SWIFTPM_TEST"] != nil {
40-
base = BuildParameters.swiftpmTestCache
41-
} else {
42-
base = buildPath
33+
if let path = Process.env["SWIFTPM_TESTS_MODULECACHE"] {
34+
return AbsolutePath(path)
4335
}
44-
return base.appending(component: "ModuleCache")
36+
return buildPath.appending(component: "ModuleCache")
4537
}
4638

4739
/// The path to the data directory.

Sources/Commands/SwiftTool.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,6 @@ public class SwiftTool<Options: ToolOptions> {
675675
let allowedDirectories = [
676676
tempDir,
677677
buildPath,
678-
BuildParameters.swiftpmTestCache
679678
].map(resolveSymlinks)
680679
args += ["sandbox-exec", "-p", sandboxProfile(allowedDirectories: allowedDirectories)]
681680
}
@@ -842,7 +841,7 @@ private func findPackageRoot() -> AbsolutePath? {
842841
/// Returns the build path from the environment, if present.
843842
private func getEnvBuildPath(workingDir: AbsolutePath) -> AbsolutePath? {
844843
// Don't rely on build path from env for SwiftPM's own tests.
845-
guard Process.env["IS_SWIFTPM_TEST"] == nil else { return nil }
844+
guard Process.env["SWIFTPM_TESTS_MODULECACHE"] == nil else { return nil }
846845
guard let env = Process.env["SWIFTPM_BUILD_DIR"] else { return nil }
847846
return AbsolutePath(env, relativeTo: workingDir)
848847
}

Sources/PackageLoading/ManifestLoader.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,21 @@ public final class ManifestLoader: ManifestLoaderProtocol {
384384
let runtimePath = self.runtimePath(for: manifestVersion).pathString
385385
let interpreterFlags = self.interpreterFlags(for: manifestVersion)
386386

387+
// FIXME: Workaround for the module cache bug that's been haunting Swift CI
388+
// <rdar://problem/48443680>
389+
let moduleCachePath = Process.env["SWIFTPM_TESTS_MODULECACHE"]
390+
387391
var cmd = [String]()
388392
#if os(macOS)
389393
// If enabled, use sandbox-exec on macOS. This provides some safety against
390394
// arbitrary code execution when parsing manifest files. We only allow
391395
// the permissions which are absolutely necessary for manifest parsing.
392396
if isManifestSandboxEnabled {
393-
cmd += ["sandbox-exec", "-p", sandboxProfile(cacheDir)]
397+
let cacheDirs = [
398+
cacheDir,
399+
moduleCachePath.map{ AbsolutePath($0) }
400+
].compactMap{$0}
401+
cmd += ["sandbox-exec", "-p", sandboxProfile(cacheDirs)]
394402
}
395403
#endif
396404
cmd += [resources.swiftCompiler.pathString]
@@ -399,6 +407,9 @@ public final class ManifestLoader: ManifestLoaderProtocol {
399407
cmd += verbosity.ccArgs
400408
cmd += ["-L", runtimePath, "-lPackageDescription"]
401409
cmd += interpreterFlags
410+
if let moduleCachePath = moduleCachePath {
411+
cmd += ["-module-cache-path", moduleCachePath]
412+
}
402413

403414
// Add the arguments for emitting serialized diagnostics, if requested.
404415
if serializedDiagnostics, cacheDir != nil {
@@ -542,7 +553,7 @@ public final class ManifestLoader: ManifestLoaderProtocol {
542553
}
543554

544555
/// Returns the sandbox profile to be used when parsing manifest on macOS.
545-
private func sandboxProfile(_ cacheDir: AbsolutePath? = nil) -> String {
556+
private func sandboxProfile(_ cacheDirs: [AbsolutePath] = []) -> String {
546557
let stream = BufferedOutputByteStream()
547558
stream <<< "(version 1)" <<< "\n"
548559
// Deny everything by default.
@@ -559,7 +570,7 @@ private func sandboxProfile(_ cacheDir: AbsolutePath? = nil) -> String {
559570
for directory in Platform.darwinCacheDirectories() {
560571
stream <<< " (regex #\"^\(directory.pathString)/org\\.llvm\\.clang.*\")" <<< "\n"
561572
}
562-
if let cacheDir = cacheDir {
573+
for cacheDir in cacheDirs {
563574
stream <<< " (subpath \"\(cacheDir.pathString)\")" <<< "\n"
564575
}
565576
stream <<< ")" <<< "\n"

Sources/TestSupport/SwiftPMProduct.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public enum SwiftPMProduct {
115115
#endif
116116
// FIXME: We use this private environment variable hack to be able to
117117
// create special conditions in swift-build for swiftpm tests.
118-
environment["IS_SWIFTPM_TEST"] = "1"
118+
environment["SWIFTPM_TESTS_MODULECACHE"] = self.path.parentDirectory.pathString
119119
environment["SDKROOT"] = nil
120120

121121
var completeArgs = [path.pathString]

0 commit comments

Comments
 (0)