Skip to content

Commit a8d89fe

Browse files
authored
Fix artifactPath used for binary targets in PIF (#9301)
The path of a binary module is always the root, whereas the artifactPath points to the artifact bundle / xcframework. Ensure we use the latter when generating file references in PIF so that we can link binary artifacts properly.
1 parent 56ba416 commit a8d89fe

File tree

5 files changed

+127
-55
lines changed

5 files changed

+127
-55
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "2600"
4+
version = "1.7">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES"
8+
buildArchitectures = "Automatic">
9+
<BuildActionEntries>
10+
<BuildActionEntry
11+
buildForTesting = "YES"
12+
buildForRunning = "YES"
13+
buildForProfiling = "YES"
14+
buildForArchiving = "YES"
15+
buildForAnalyzing = "YES">
16+
<BuildableReference
17+
BuildableIdentifier = "primary"
18+
BlueprintIdentifier = "63A1B3E323FB4B26001B7732"
19+
BuildableName = "SwiftFramework.framework"
20+
BlueprintName = "SwiftFramework"
21+
ReferencedContainer = "container:SwiftFramework.xcodeproj">
22+
</BuildableReference>
23+
</BuildActionEntry>
24+
</BuildActionEntries>
25+
</BuildAction>
26+
<TestAction
27+
buildConfiguration = "Debug"
28+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
29+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
30+
shouldUseLaunchSchemeArgsEnv = "YES"
31+
shouldAutocreateTestPlan = "YES">
32+
</TestAction>
33+
<LaunchAction
34+
buildConfiguration = "Debug"
35+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37+
launchStyle = "0"
38+
useCustomWorkingDirectory = "NO"
39+
ignoresPersistentStateOnLaunch = "NO"
40+
debugDocumentVersioning = "YES"
41+
allowLocationSimulation = "YES">
42+
</LaunchAction>
43+
<ProfileAction
44+
buildConfiguration = "Release"
45+
shouldUseLaunchSchemeArgsEnv = "YES"
46+
savedToolIdentifier = ""
47+
useCustomWorkingDirectory = "NO"
48+
debugDocumentVersioning = "YES">
49+
<MacroExpansion>
50+
<BuildableReference
51+
BuildableIdentifier = "primary"
52+
BlueprintIdentifier = "63A1B3E323FB4B26001B7732"
53+
BuildableName = "SwiftFramework.framework"
54+
BlueprintName = "SwiftFramework"
55+
ReferencedContainer = "container:SwiftFramework.xcodeproj">
56+
</BuildableReference>
57+
</MacroExpansion>
58+
</ProfileAction>
59+
<AnalyzeAction
60+
buildConfiguration = "Debug">
61+
</AnalyzeAction>
62+
<ArchiveAction
63+
buildConfiguration = "Release"
64+
revealArchiveInOrganizer = "YES">
65+
</ArchiveAction>
66+
<InstallAction
67+
buildConfiguration = "Release">
68+
</InstallAction>
69+
</Scheme>

Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import struct Basics.SourceControlURL
2121

2222
import class PackageModel.Manifest
2323
import class PackageModel.Module
24+
import class PackageModel.BinaryModule
2425
import class PackageModel.Product
2526
import class PackageModel.SystemLibraryModule
2627

@@ -639,8 +640,12 @@ extension PackagePIFProjectBuilder {
639640
}
640641

641642
case .binary:
643+
guard let binaryModule = moduleDependency.underlying as? BinaryModule else {
644+
log(.error, "'\(moduleDependency.name)' is a binary dependency, but its underlying module was not")
645+
break
646+
}
642647
let binaryReference = self.binaryGroup.addFileReference { id in
643-
FileReference(id: id, path: moduleDependency.path.pathString)
648+
FileReference(id: id, path: (binaryModule.artifactPath.pathString))
644649
}
645650
if shouldLinkProduct {
646651
self.project[keyPath: sourceModuleTargetKeyPath].addLibrary { id in

Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Products.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,12 @@ extension PackagePIFProjectBuilder {
339339

340340
switch moduleDependency.type {
341341
case .binary:
342+
guard let binaryModule = moduleDependency.underlying as? BinaryModule else {
343+
log(.error, "'\(moduleDependency.name)' is a binary dependency, but its underlying module was not")
344+
break
345+
}
342346
let binaryFileRef = self.binaryGroup.addFileReference { id in
343-
FileReference(id: id, path: moduleDependency.path.pathString)
347+
FileReference(id: id, path: binaryModule.artifactPath.pathString)
344348
}
345349
let toolsVersion = self.package.manifest.toolsVersion
346350
self.project[keyPath: mainModuleTargetKeyPath].addLibrary { id in
@@ -720,7 +724,7 @@ extension PackagePIFProjectBuilder {
720724

721725
if let binaryTarget = moduleDependency.underlying as? BinaryModule {
722726
let binaryFileRef = self.binaryGroup.addFileReference { id in
723-
FileReference(id: id, path: binaryTarget.path.pathString)
727+
FileReference(id: id, path: binaryTarget.artifactPath.pathString)
724728
}
725729
let toolsVersion = package.manifest.toolsVersion
726730
self.project[keyPath: libraryUmbrellaTargetKeyPath].addLibrary { id in

Sources/_IntegrationTestSupport/Helpers.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ package func _sh(
113113
}
114114

115115
public func binaryTargetsFixture(_ closure: (AbsolutePath) async throws -> Void) async throws {
116-
try await fixture(name: "BinaryTargets") { fixturePath in
116+
try await fixture(name: "BinaryTargets", removeFixturePathOnDeinit: false) { fixturePath in
117117
let inputsPath = fixturePath.appending(component: "Inputs")
118118
let packagePath = fixturePath.appending(component: "TestBinary")
119119

@@ -157,7 +157,7 @@ public func binaryTargetsFixture(_ closure: (AbsolutePath) async throws -> Void)
157157
let projectPath = subpath.appending(component: "SwiftFramework.xcodeproj")
158158
try sh(
159159
xcodebuild, "-project", projectPath, "-scheme", "SwiftFramework",
160-
"-derivedDataPath", tmpDir, "COMPILER_INDEX_STORE_ENABLE=NO"
160+
"-derivedDataPath", tmpDir, "COMPILER_INDEX_STORE_ENABLE=NO", "DEPLOYMENT_LOCATION=NO"
161161
)
162162
let frameworkPath = try AbsolutePath(
163163
validating: "Build/Products/Debug/SwiftFramework.framework",
@@ -186,4 +186,4 @@ extension AsyncProcessResult {
186186
\((try? utf8stderrOutput()) ?? "")
187187
"""
188188
}
189-
}
189+
}

Tests/IntegrationTests/SwiftPMTests.swift

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -20,65 +20,59 @@ import struct SPMBuildCore.BuildSystemProvider
2020
.tags(Tag.TestSize.large)
2121
)
2222
private struct SwiftPMTests {
23-
@Test(.requireHostOS(.macOS))
24-
func binaryTargets() async throws {
25-
await withKnownIssue("error: the path does not point to a valid framework:") {
26-
try await binaryTargetsFixture { fixturePath in
27-
do {
28-
await withKnownIssue("error: local binary target ... does not contain a binary artifact") {
29-
let runOutput = try await executeSwiftRun(
30-
fixturePath,
31-
"exe",
32-
buildSystem: .native,
33-
)
34-
#expect(!runOutput.stderr.contains("error:"))
35-
#expect(
36-
runOutput.stdout == """
23+
@Test(.requireHostOS(.macOS), arguments: [BuildSystemProvider.Kind.native, .swiftbuild])
24+
func binaryTargets(buildSystem: BuildSystemProvider.Kind) async throws {
25+
try await binaryTargetsFixture { fixturePath in
26+
do {
27+
let runOutput = try await executeSwiftRun(
28+
fixturePath,
29+
"exe",
30+
buildSystem: buildSystem,
31+
)
32+
#expect(!runOutput.stderr.contains("error:"))
33+
#expect(
34+
runOutput.stdout == """
3735
SwiftFramework()
3836
Library(framework: SwiftFramework.SwiftFramework())
39-
37+
4038
"""
41-
)
42-
}
43-
}
44-
45-
do {
46-
await withKnownIssue("error: local binary target ... does not contain a binary artifact") {
47-
let runOutput = try await executeSwiftRun(fixturePath, "cexe", buildSystem: .native)
48-
#expect(!runOutput.stderr.contains("error:"))
49-
#expect(runOutput.stdout.contains("<CLibrary: "))
50-
}
51-
}
39+
)
40+
}
5241

53-
do {
54-
let invalidPath = fixturePath.appending(component: "SwiftFramework.xcframework")
42+
do {
43+
let runOutput = try await executeSwiftRun(fixturePath, "cexe", buildSystem: buildSystem)
44+
#expect(!runOutput.stderr.contains("error:"))
45+
#expect(runOutput.stdout.contains("<CLibrary: "))
46+
}
5547

56-
await #expect {
57-
try await executeSwiftPackage(
58-
fixturePath,
59-
extraArgs: ["compute-checksum", invalidPath.pathString],
60-
buildSystem: .native,
61-
)
62-
} throws: { error in
63-
// The order of supported extensions is not ordered, and changes.
64-
// '...supported extensions are: zip, tar.gz, tar'
65-
// '...supported extensions are: tar.gz, zip, tar'
66-
// Only check for the start of that string.
67-
// TODO: error.stderr.contains("error: unexpected file type; supported extensions are:")
68-
return true
69-
}
48+
do {
49+
let invalidPath = fixturePath.appending(component: "SwiftFramework.xcframework")
7050

71-
let validPath = fixturePath.appending(component: "SwiftFramework.zip")
72-
let packageOutput = try await executeSwiftPackage(
51+
await #expect {
52+
try await executeSwiftPackage(
7353
fixturePath,
74-
extraArgs: ["compute-checksum", validPath.pathString],
54+
extraArgs: ["compute-checksum", invalidPath.pathString],
7555
buildSystem: .native,
7656
)
77-
#expect(
78-
packageOutput.stdout.spm_chomp()
79-
== "d1f202b1bfe04dea30b2bc4038f8059dcd75a5a176f1d81fcaedb6d3597d1158"
80-
)
57+
} throws: { error in
58+
// The order of supported extensions is not ordered, and changes.
59+
// '...supported extensions are: zip, tar.gz, tar'
60+
// '...supported extensions are: tar.gz, zip, tar'
61+
// Only check for the start of that string.
62+
// TODO: error.stderr.contains("error: unexpected file type; supported extensions are:")
63+
return true
8164
}
65+
66+
let validPath = fixturePath.appending(component: "SwiftFramework.zip")
67+
let packageOutput = try await executeSwiftPackage(
68+
fixturePath,
69+
extraArgs: ["compute-checksum", validPath.pathString],
70+
buildSystem: .native,
71+
)
72+
#expect(
73+
packageOutput.stdout.spm_chomp()
74+
== "d1f202b1bfe04dea30b2bc4038f8059dcd75a5a176f1d81fcaedb6d3597d1158"
75+
)
8276
}
8377
}
8478
}

0 commit comments

Comments
 (0)