Skip to content

Commit 1914e8d

Browse files
committed
SwiftBuild: add scratch path symbolic links
The native build system would create the `debug` and `release` symbolic link in the scratch path as they were the original output location before triple support was added. Although this is not an officially support feature, add the `debug` and `release` symbolic links when using Swift Build to ease the transition until a better solution is avaiable. Relates to: #9963 Issue: rdar://175144467
1 parent 2f50607 commit 1914e8d

5 files changed

Lines changed: 48 additions & 0 deletions

File tree

Sources/CoreCommands/SwiftCommandState.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ public final class SwiftCommandState {
10011001
}
10021002

10031003
return try BuildParameters(
1004+
scratchPath: self.scratchDirectory,
10041005
destination: destination,
10051006
dataPath: dataPath,
10061007
configuration: self.options.build.configuration ?? self.preferredBuildConfiguration,

Sources/SPMBuildCore/BuildParameters/BuildParameters.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public struct BuildParameters: Encodable {
4747
case target
4848
}
4949

50+
// The scrath path
51+
package let scratchPath: Basics.AbsolutePath
52+
5053
/// The destination these parameters are going to be used for.
5154
public var destination: Destination
5255

@@ -161,6 +164,7 @@ public struct BuildParameters: Encodable {
161164
public var apiDigesterMode: APIDigesterMode?
162165

163166
public init(
167+
scratchPath: Basics.AbsolutePath,
164168
destination: Destination,
165169
dataPath: Basics.AbsolutePath,
166170
configuration: BuildConfiguration,
@@ -185,6 +189,8 @@ public struct BuildParameters: Encodable {
185189
testingParameters: Testing = .init(),
186190
apiDigesterMode: APIDigesterMode? = nil
187191
) throws {
192+
self.scratchPath = scratchPath
193+
188194
// Default to the unversioned triple if none is provided so that we defer to the package's requested deployment target, for Darwin platforms. For other platforms, continue to include the version since those don't have the concept of a package-specified version, and the version is meaningful for some platforms including Android and FreeBSD.
189195
let triple = try triple ?? {
190196
let hostTriple = try Triple.getHostTriple(

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,12 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
406406
replArguments: nil,
407407
)
408408

409+
defer {
410+
createBuildSymbolicLinks(
411+
scratchPath: self.buildParameters.scratchPath,
412+
buildConfig: self.buildParameters.configuration,
413+
)
414+
}
409415
guard !buildParameters.shouldSkipBuilding else {
410416
result.serializedDiagnosticPathsByTargetName = .failure(StringError("Building was skipped"))
411417
return result
@@ -424,6 +430,38 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
424430
)
425431
}
426432

433+
func createBuildSymbolicLinks(
434+
scratchPath: Basics.AbsolutePath,
435+
buildConfig: BuildConfiguration,
436+
) {
437+
let oldBuildPath = scratchPath.appending(component: buildConfig.dirname)
438+
if self.fileSystem.exists(oldBuildPath) {
439+
do {
440+
// This does not delete the directory pointed to by the symbolic link
441+
try self.fileSystem.removeFileTree(oldBuildPath)
442+
}
443+
catch {
444+
self.observabilityScope.emit(
445+
warning: "unable to delete \(oldBuildPath), skip creating symbolic link",
446+
underlyingError: error
447+
)
448+
}
449+
}
450+
451+
do {
452+
try self.fileSystem.createSymbolicLink(
453+
oldBuildPath,
454+
pointingAt: self.buildParameters.buildPath,
455+
relative: true
456+
)
457+
} catch {
458+
self.observabilityScope.emit(
459+
warning: "unable to create symbolic link at \(oldBuildPath)",
460+
underlyingError: error
461+
)
462+
}
463+
}
464+
427465
/// Compiles any plugins specified or implied by the build subset, returning
428466
/// true if the build should proceed. Throws an error in case of failure. A
429467
/// reason why the build might not proceed even on success is if only plugins

Sources/_InternalTestSupport/MockBuildTestHelper.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public let defaultTargetTriple: String = hostTriple.tripleString
8888
#endif
8989

9090
public func mockBuildParameters(
91+
scratchDirectory: AbsolutePath? = nil,
9192
destination: BuildParameters.Destination,
9293
buildPath: AbsolutePath? = nil,
9394
config: BuildConfiguration = .debug,
@@ -110,6 +111,7 @@ public func mockBuildParameters(
110111
numberOfWorkers: UInt32 = 3,
111112
) -> BuildParameters {
112113
try! BuildParameters(
114+
scratchPath: scratchDirectory ?? AbsolutePath("/path/to/scratch"),
113115
destination: destination,
114116
dataPath: buildPath ?? AbsolutePath("/path/to/build").appending(triple.tripleString),
115117
configuration: config,

Sources/swift-bootstrap/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ struct SwiftBootstrapBuildTool: AsyncParsableCommand {
311311
)
312312

313313
return try BuildParameters(
314+
scratchPath: scratchDirectory,
314315
destination: .target,
315316
dataPath: dataPath,
316317
configuration: configuration,

0 commit comments

Comments
 (0)