Skip to content

Commit b9a8aa2

Browse files
MaxDesiatovfurby-tm
authored andcommitted
Fix incorrect paths for library products with explicit linkage (swiftlang#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
1 parent 599d693 commit b9a8aa2

File tree

4 files changed

+116
-11
lines changed

4 files changed

+116
-11
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
@@ -21,6 +21,7 @@ import func PackageGraph.loadModulesGraph
2121

2222
import class PackageModel.Manifest
2323
import struct PackageModel.ProductDescription
24+
import enum PackageModel.ProductType
2425
import struct PackageModel.TargetDescription
2526
import protocol TSCBasic.FileSystem
2627
import class TSCBasic.InMemoryFileSystem
@@ -258,7 +259,7 @@ package func macrosTestsPackageGraph() throws -> MockPackageGraph {
258259
return (graph, fs, observability.topScope)
259260
}
260261

261-
package func trivialPackageGraph(pkgRootPath: AbsolutePath) throws -> MockPackageGraph {
262+
package func trivialPackageGraph() throws -> MockPackageGraph {
262263
let fs = InMemoryFileSystem(
263264
emptyFiles:
264265
"/Pkg/Sources/app/main.swift",
@@ -288,7 +289,7 @@ package func trivialPackageGraph(pkgRootPath: AbsolutePath) throws -> MockPackag
288289
return (graph, fs, observability.topScope)
289290
}
290291

291-
package func embeddedCxxInteropPackageGraph(pkgRootPath: AbsolutePath) throws -> MockPackageGraph {
292+
package func embeddedCxxInteropPackageGraph() throws -> MockPackageGraph {
292293
let fs = InMemoryFileSystem(
293294
emptyFiles:
294295
"/Pkg/Sources/app/main.swift",
@@ -329,3 +330,66 @@ package func embeddedCxxInteropPackageGraph(pkgRootPath: AbsolutePath) throws ->
329330

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

Tests/BuildTests/CrossCompilationBuildPlanTests.swift

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ 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
import func SPMTestSupport.embeddedCxxInteropPackageGraph
2627
import func SPMTestSupport.macrosPackageGraph
2728
import func SPMTestSupport.macrosTestsPackageGraph
2829
import func SPMTestSupport.mockBuildParameters
30+
import func SPMTestSupport.toolsExplicitLibrariesGraph
2931
import func SPMTestSupport.trivialPackageGraph
3032

3133
import struct SPMTestSupport.BuildPlanResult
@@ -37,7 +39,7 @@ import XCTest
3739

3840
final class CrossCompilationBuildPlanTests: XCTestCase {
3941
func testEmbeddedWasmTarget() throws {
40-
var (graph, fs, observabilityScope) = try trivialPackageGraph(pkgRootPath: "/Pkg")
42+
var (graph, fs, observabilityScope) = try trivialPackageGraph()
4143

4244
let triple = try Triple("wasm32-unknown-none-wasm")
4345
var parameters = mockBuildParameters(triple: triple)
@@ -68,7 +70,7 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
6870
]
6971
)
7072

71-
(graph, fs, observabilityScope) = try embeddedCxxInteropPackageGraph(pkgRootPath: "/Pkg")
73+
(graph, fs, observabilityScope) = try embeddedCxxInteropPackageGraph()
7274

7375
result = try BuildPlanResult(plan: BuildPlan(
7476
buildParameters: parameters,
@@ -98,9 +100,7 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
98100
}
99101

100102
func testWasmTargetRelease() throws {
101-
let pkgPath = AbsolutePath("/Pkg")
102-
103-
let (graph, fs, observabilityScope) = try trivialPackageGraph(pkgRootPath: pkgPath)
103+
let (graph, fs, observabilityScope) = try trivialPackageGraph()
104104

105105
var parameters = mockBuildParameters(
106106
config: .release, triple: .wasi, linkerDeadStrip: true
@@ -133,7 +133,7 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
133133
func testWASITarget() throws {
134134
let pkgPath = AbsolutePath("/Pkg")
135135

136-
let (graph, fs, observabilityScope) = try trivialPackageGraph(pkgRootPath: pkgPath)
136+
let (graph, fs, observabilityScope) = try trivialPackageGraph()
137137

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

311352
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)