From dce91a08c603d6a1befad3e03d28a820c97c33fe Mon Sep 17 00:00:00 2001 From: Owen Voorhees Date: Tue, 28 Oct 2025 11:22:50 -0700 Subject: [PATCH] Fix artifactPath used for binary targets in PIF --- .../xcschemes/SwiftFramework.xcscheme | 69 ++++++++++++++ .../PackagePIFProjectBuilder+Modules.swift | 7 +- .../PackagePIFProjectBuilder+Products.swift | 8 +- Sources/_IntegrationTestSupport/Helpers.swift | 6 +- Tests/IntegrationTests/SwiftPMTests.swift | 92 +++++++++---------- 5 files changed, 127 insertions(+), 55 deletions(-) create mode 100644 Fixtures/BinaryTargets/Inputs/SwiftFramework/SwiftFramework.xcodeproj/xcshareddata/xcschemes/SwiftFramework.xcscheme diff --git a/Fixtures/BinaryTargets/Inputs/SwiftFramework/SwiftFramework.xcodeproj/xcshareddata/xcschemes/SwiftFramework.xcscheme b/Fixtures/BinaryTargets/Inputs/SwiftFramework/SwiftFramework.xcodeproj/xcshareddata/xcschemes/SwiftFramework.xcscheme new file mode 100644 index 00000000000..3c42c6b98cd --- /dev/null +++ b/Fixtures/BinaryTargets/Inputs/SwiftFramework/SwiftFramework.xcodeproj/xcshareddata/xcschemes/SwiftFramework.xcscheme @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift index b0fc05cbe03..7032e95b726 100644 --- a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift +++ b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift @@ -21,6 +21,7 @@ import struct Basics.SourceControlURL import class PackageModel.Manifest import class PackageModel.Module +import class PackageModel.BinaryModule import class PackageModel.Product import class PackageModel.SystemLibraryModule @@ -629,8 +630,12 @@ extension PackagePIFProjectBuilder { } case .binary: + guard let binaryModule = moduleDependency.underlying as? BinaryModule else { + log(.error, "'\(moduleDependency.name)' is a binary dependency, but its underlying module was not") + break + } let binaryReference = self.binaryGroup.addFileReference { id in - FileReference(id: id, path: moduleDependency.path.pathString) + FileReference(id: id, path: (binaryModule.artifactPath.pathString)) } if shouldLinkProduct { self.project[keyPath: sourceModuleTargetKeyPath].addLibrary { id in diff --git a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Products.swift b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Products.swift index aba997f917d..e9f1234e784 100644 --- a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Products.swift +++ b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Products.swift @@ -339,8 +339,12 @@ extension PackagePIFProjectBuilder { switch moduleDependency.type { case .binary: + guard let binaryModule = moduleDependency.underlying as? BinaryModule else { + log(.error, "'\(moduleDependency.name)' is a binary dependency, but its underlying module was not") + break + } let binaryFileRef = self.binaryGroup.addFileReference { id in - FileReference(id: id, path: moduleDependency.path.pathString) + FileReference(id: id, path: binaryModule.artifactPath.pathString) } let toolsVersion = self.package.manifest.toolsVersion self.project[keyPath: mainModuleTargetKeyPath].addLibrary { id in @@ -720,7 +724,7 @@ extension PackagePIFProjectBuilder { if let binaryTarget = moduleDependency.underlying as? BinaryModule { let binaryFileRef = self.binaryGroup.addFileReference { id in - FileReference(id: id, path: binaryTarget.path.pathString) + FileReference(id: id, path: binaryTarget.artifactPath.pathString) } let toolsVersion = package.manifest.toolsVersion self.project[keyPath: libraryUmbrellaTargetKeyPath].addLibrary { id in diff --git a/Sources/_IntegrationTestSupport/Helpers.swift b/Sources/_IntegrationTestSupport/Helpers.swift index 41583bb8a3c..7dd29842e09 100644 --- a/Sources/_IntegrationTestSupport/Helpers.swift +++ b/Sources/_IntegrationTestSupport/Helpers.swift @@ -113,7 +113,7 @@ package func _sh( } public func binaryTargetsFixture(_ closure: (AbsolutePath) async throws -> Void) async throws { - try await fixture(name: "BinaryTargets") { fixturePath in + try await fixture(name: "BinaryTargets", removeFixturePathOnDeinit: false) { fixturePath in let inputsPath = fixturePath.appending(component: "Inputs") let packagePath = fixturePath.appending(component: "TestBinary") @@ -157,7 +157,7 @@ public func binaryTargetsFixture(_ closure: (AbsolutePath) async throws -> Void) let projectPath = subpath.appending(component: "SwiftFramework.xcodeproj") try sh( xcodebuild, "-project", projectPath, "-scheme", "SwiftFramework", - "-derivedDataPath", tmpDir, "COMPILER_INDEX_STORE_ENABLE=NO" + "-derivedDataPath", tmpDir, "COMPILER_INDEX_STORE_ENABLE=NO", "DEPLOYMENT_LOCATION=NO" ) let frameworkPath = try AbsolutePath( validating: "Build/Products/Debug/SwiftFramework.framework", @@ -186,4 +186,4 @@ extension AsyncProcessResult { \((try? utf8stderrOutput()) ?? "") """ } -} \ No newline at end of file +} diff --git a/Tests/IntegrationTests/SwiftPMTests.swift b/Tests/IntegrationTests/SwiftPMTests.swift index c2fd11b8666..ba4e43828cd 100644 --- a/Tests/IntegrationTests/SwiftPMTests.swift +++ b/Tests/IntegrationTests/SwiftPMTests.swift @@ -20,65 +20,59 @@ import struct SPMBuildCore.BuildSystemProvider .tags(Tag.TestSize.large) ) private struct SwiftPMTests { - @Test(.requireHostOS(.macOS)) - func binaryTargets() async throws { - await withKnownIssue("error: the path does not point to a valid framework:") { - try await binaryTargetsFixture { fixturePath in - do { - await withKnownIssue("error: local binary target ... does not contain a binary artifact") { - let runOutput = try await executeSwiftRun( - fixturePath, - "exe", - buildSystem: .native, - ) - #expect(!runOutput.stderr.contains("error:")) - #expect( - runOutput.stdout == """ + @Test(.requireHostOS(.macOS), arguments: [BuildSystemProvider.Kind.native, .swiftbuild]) + func binaryTargets(buildSystem: BuildSystemProvider.Kind) async throws { + try await binaryTargetsFixture { fixturePath in + do { + let runOutput = try await executeSwiftRun( + fixturePath, + "exe", + buildSystem: buildSystem, + ) + #expect(!runOutput.stderr.contains("error:")) + #expect( + runOutput.stdout == """ SwiftFramework() Library(framework: SwiftFramework.SwiftFramework()) - + """ - ) - } - } - - do { - await withKnownIssue("error: local binary target ... does not contain a binary artifact") { - let runOutput = try await executeSwiftRun(fixturePath, "cexe", buildSystem: .native) - #expect(!runOutput.stderr.contains("error:")) - #expect(runOutput.stdout.contains("