Skip to content

Commit 287f03b

Browse files
committed
Fix incorrect paths for library products with explicit linkage (#7519)
Library products declared with `.static` or `.dynamic` linkage didn't have a `-tools` suffix in their file names when built as dependencies of macros. This change resolves the inconsistency and adds corresponding build plan tests. The regression in question broke the compatibility test suite, which had [an old version of `swift-power-assert`](https://github.com/kishikawakatsumi/swift-power-assert/blob/a60cb50/Package.swift) depending on an old version of `swift-syntax` with explicit `.static` linkage for its products. rdar://127170225 (cherry picked from commit 8db2401) # Conflicts: # Tests/BuildTests/CrossCompilationBuildPlanTests.swift
1 parent e27b9f0 commit 287f03b

File tree

4 files changed

+116
-13
lines changed

4 files changed

+116
-13
lines changed

Sources/SPMBuildCore/BuildParameters/BuildParameters.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ public struct BuildParameters: Encodable {
243243

244244
/// Returns the path to the dynamic library of a product for the current build parameters.
245245
func potentialDynamicLibraryPath(for product: ResolvedProduct) throws -> RelativePath {
246-
try RelativePath(validating: "\(self.triple.dynamicLibraryPrefix)\(product.name)\(self.triple.dynamicLibraryExtension)")
246+
try RelativePath(validating: "\(self.triple.dynamicLibraryPrefix)\(product.name)\(self.suffix(triple: product.buildTriple))\(self.triple.dynamicLibraryExtension)")
247247
}
248248

249249
/// Returns the path to the binary of a product for the current build parameters, relative to the build directory.
@@ -254,7 +254,7 @@ public struct BuildParameters: Encodable {
254254
case .executable, .snippet:
255255
return potentialExecutablePath
256256
case .library(.static):
257-
return try RelativePath(validating: "lib\(product.name)\(self.triple.staticLibraryExtension)")
257+
return try RelativePath(validating: "lib\(product.name)\(self.suffix(triple: product.buildTriple))\(self.triple.staticLibraryExtension)")
258258
case .library(.dynamic):
259259
return try potentialDynamicLibraryPath(for: product)
260260
case .library(.automatic), .plugin:

Sources/SPMTestSupport/MockPackageGraphs.swift

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import class Basics.ObservabilityScope
1616
import struct PackageGraph.ModulesGraph
1717
import class PackageModel.Manifest
1818
import struct PackageModel.ProductDescription
19+
import enum PackageModel.ProductType
1920
import struct PackageModel.TargetDescription
2021
import protocol TSCBasic.FileSystem
2122
import class TSCBasic.InMemoryFileSystem
@@ -253,7 +254,7 @@ package func macrosTestsPackageGraph() throws -> MockPackageGraph {
253254
return (graph, fs, observability.topScope)
254255
}
255256

256-
package func trivialPackageGraph(pkgRootPath: AbsolutePath) throws -> MockPackageGraph {
257+
package func trivialPackageGraph() throws -> MockPackageGraph {
257258
let fs = InMemoryFileSystem(
258259
emptyFiles:
259260
"/Pkg/Sources/app/main.swift",
@@ -283,7 +284,7 @@ package func trivialPackageGraph(pkgRootPath: AbsolutePath) throws -> MockPackag
283284
return (graph, fs, observability.topScope)
284285
}
285286

286-
package func embeddedCxxInteropPackageGraph(pkgRootPath: AbsolutePath) throws -> MockPackageGraph {
287+
package func embeddedCxxInteropPackageGraph() throws -> MockPackageGraph {
287288
let fs = InMemoryFileSystem(
288289
emptyFiles:
289290
"/Pkg/Sources/app/main.swift",
@@ -324,3 +325,66 @@ package func embeddedCxxInteropPackageGraph(pkgRootPath: AbsolutePath) throws ->
324325

325326
return (graph, fs, observability.topScope)
326327
}
328+
329+
package func toolsExplicitLibrariesGraph(linkage: ProductType.LibraryType) throws -> MockPackageGraph {
330+
let fs = InMemoryFileSystem(emptyFiles:
331+
"/swift-mmio/Sources/MMIOMacros/source.swift",
332+
"/swift-mmio/Sources/MMIOMacrosTests/source.swift",
333+
"/swift-syntax/Sources/SwiftSyntax/source.swift"
334+
)
335+
336+
let observability = ObservabilitySystem.makeForTesting()
337+
let graph = try loadModulesGraph(
338+
fileSystem: fs,
339+
manifests: [
340+
Manifest.createRootManifest(
341+
displayName: "swift-mmio",
342+
path: "/swift-mmio",
343+
dependencies: [
344+
.localSourceControl(
345+
path: "/swift-syntax",
346+
requirement: .upToNextMajor(from: "1.0.0")
347+
)
348+
],
349+
targets: [
350+
TargetDescription(
351+
name: "MMIOMacros",
352+
dependencies: [
353+
.product(name: "SwiftSyntax", package: "swift-syntax"),
354+
],
355+
type: .macro
356+
),
357+
TargetDescription(
358+
name: "MMIOMacrosTests",
359+
dependencies: [
360+
.target(name: "MMIOMacros"),
361+
],
362+
type: .test
363+
)
364+
]
365+
),
366+
Manifest.createFileSystemManifest(
367+
displayName: "swift-syntax",
368+
path: "/swift-syntax",
369+
products: [
370+
ProductDescription(
371+
name: "SwiftSyntax",
372+
type: .library(linkage),
373+
targets: ["SwiftSyntax"]
374+
),
375+
],
376+
targets: [
377+
TargetDescription(
378+
name: "SwiftSyntax",
379+
dependencies: []
380+
),
381+
]
382+
),
383+
],
384+
observabilityScope: observability.topScope
385+
)
386+
387+
XCTAssertNoDiagnostics(observability.diagnostics)
388+
389+
return (graph, fs, observability.topScope)
390+
}

Tests/BuildTests/CrossCompilationBuildPlanTests.swift

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import struct Basics.Triple
2020
import enum PackageGraph.BuildTriple
2121
import class PackageModel.Manifest
2222
import struct PackageModel.TargetDescription
23+
import enum PackageModel.ProductType
2324
import func SPMTestSupport.loadPackageGraph
2425

2526
@_spi(SwiftPMInternal)
@@ -29,8 +30,7 @@ import func SPMTestSupport.embeddedCxxInteropPackageGraph
2930
import func SPMTestSupport.macrosPackageGraph
3031
import func SPMTestSupport.macrosTestsPackageGraph
3132
import func SPMTestSupport.mockBuildParameters
32-
33-
@_spi(SwiftPMInternal)
33+
import func SPMTestSupport.toolsExplicitLibrariesGraph
3434
import func SPMTestSupport.trivialPackageGraph
3535

3636
import struct SPMTestSupport.BuildPlanResult
@@ -42,7 +42,7 @@ import XCTest
4242

4343
final class CrossCompilationBuildPlanTests: XCTestCase {
4444
func testEmbeddedWasmTarget() throws {
45-
var (graph, fs, observabilityScope) = try trivialPackageGraph(pkgRootPath: "/Pkg")
45+
var (graph, fs, observabilityScope) = try trivialPackageGraph()
4646

4747
let triple = try Triple("wasm32-unknown-none-wasm")
4848
var parameters = mockBuildParameters(triple: triple)
@@ -73,7 +73,7 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
7373
]
7474
)
7575

76-
(graph, fs, observabilityScope) = try embeddedCxxInteropPackageGraph(pkgRootPath: "/Pkg")
76+
(graph, fs, observabilityScope) = try embeddedCxxInteropPackageGraph()
7777

7878
result = try BuildPlanResult(plan: BuildPlan(
7979
buildParameters: parameters,
@@ -103,9 +103,7 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
103103
}
104104

105105
func testWasmTargetRelease() throws {
106-
let pkgPath = AbsolutePath("/Pkg")
107-
108-
let (graph, fs, observabilityScope) = try trivialPackageGraph(pkgRootPath: pkgPath)
106+
let (graph, fs, observabilityScope) = try trivialPackageGraph()
109107

110108
var parameters = mockBuildParameters(
111109
config: .release, triple: .wasi, linkerDeadStrip: true
@@ -138,7 +136,7 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
138136
func testWASITarget() throws {
139137
let pkgPath = AbsolutePath("/Pkg")
140138

141-
let (graph, fs, observabilityScope) = try trivialPackageGraph(pkgRootPath: pkgPath)
139+
let (graph, fs, observabilityScope) = try trivialPackageGraph()
142140

143141
var parameters = mockBuildParameters(triple: .wasi)
144142
parameters.linkingParameters.shouldLinkStaticSwiftStdlib = true
@@ -311,6 +309,47 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
311309
]
312310
)
313311
}
312+
313+
func testToolsExplicitLibraries() throws {
314+
let destinationTriple = Triple.arm64Linux
315+
let toolsTriple = Triple.x86_64MacOS
316+
317+
for (linkage, productFileName) in [(ProductType.LibraryType.static, "libSwiftSyntax-tool.a"), (.dynamic, "libSwiftSyntax-tool.dylib")] {
318+
let (graph, fs, scope) = try toolsExplicitLibrariesGraph(linkage: linkage)
319+
let plan = try BuildPlan(
320+
destinationBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, triple: destinationTriple),
321+
toolsBuildParameters: mockBuildParameters(triple: toolsTriple),
322+
graph: graph,
323+
fileSystem: fs,
324+
observabilityScope: scope
325+
)
326+
let result = try BuildPlanResult(plan: plan)
327+
result.checkProductsCount(4)
328+
result.checkTargetsCount(6)
329+
330+
XCTAssertTrue(try result.allTargets(named: "SwiftSyntax")
331+
.map { try $0.swiftTarget() }
332+
.contains { $0.target.buildTriple == .tools })
333+
334+
try result.check(buildTriple: .tools, triple: toolsTriple, for: "swift-mmioPackageTests")
335+
try result.check(buildTriple: .tools, triple: toolsTriple, for: "swift-mmioPackageDiscoveredTests")
336+
try result.check(buildTriple: .tools, triple: toolsTriple, for: "MMIOMacros")
337+
try result.check(buildTriple: .tools, triple: toolsTriple, for: "MMIOMacrosTests")
338+
339+
let macroProducts = result.allProducts(named: "MMIOMacros")
340+
XCTAssertEqual(macroProducts.count, 1)
341+
let macroProduct = try XCTUnwrap(macroProducts.first)
342+
XCTAssertEqual(macroProduct.buildParameters.triple, toolsTriple)
343+
344+
let swiftSyntaxProducts = result.allProducts(named: "SwiftSyntax")
345+
XCTAssertEqual(swiftSyntaxProducts.count, 2)
346+
let swiftSyntaxToolsProduct = try XCTUnwrap(swiftSyntaxProducts.first { $0.product.buildTriple == .tools })
347+
let archiveArguments = try swiftSyntaxToolsProduct.archiveArguments()
348+
349+
// Verify that produced library file has a correct name
350+
XCTAssertMatch(archiveArguments, [.contains(productFileName)])
351+
}
352+
}
314353
}
315354

316355
extension BuildPlanResult {

Tests/PackageGraphTests/CrossCompilationPackageGraphTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import XCTest
2020

2121
final class CrossCompilationPackageGraphTests: XCTestCase {
2222
func testTrivialPackage() throws {
23-
let graph = try trivialPackageGraph(pkgRootPath: "/Pkg").graph
23+
let graph = try trivialPackageGraph().graph
2424
try PackageGraphTester(graph) { result in
2525
result.check(packages: "Pkg")
2626
// "SwiftSyntax" is included for both host and target triples and is not pruned on this level

0 commit comments

Comments
 (0)