Skip to content

Commit 8b11e43

Browse files
authored
Use the correct module name for executable targets combined with an executable product with a different name (#9480)
If an executable target is combined with an executable product at the PIF layer, it must retain the target's module name, so that tests which consume it can import the right module name.
1 parent 96d7b55 commit 8b11e43

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// swift-tools-version: 5.5
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "TestableExe",
6+
products: [
7+
.executable(name: "testable-exe", targets: ["TestableExe"])
8+
],
9+
targets: [
10+
.executableTarget(
11+
name: "TestableExe"
12+
),
13+
.testTarget(
14+
name: "TestableExeTests",
15+
dependencies: [
16+
"TestableExe",
17+
]
18+
),
19+
]
20+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public func functionFromTestableExecutable() {
2+
print("Hello, world")
3+
}
4+
5+
functionFromTestableExecutable()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import XCTest
2+
@testable import TestableExe
3+
4+
final class TestableExeTests: XCTestCase {
5+
func testExample() throws {
6+
functionFromTestableExecutable()
7+
}
8+
}

Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Products.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ extension PackagePIFProjectBuilder {
112112
settings[.TARGET_NAME] = product.name
113113
settings[.PACKAGE_RESOURCE_TARGET_KIND] = "regular"
114114
settings[.PRODUCT_NAME] = "$(TARGET_NAME)"
115-
settings[.PRODUCT_MODULE_NAME] = product.c99name
115+
// We must use the main module name here instead of the product name, because they're not guranteed to be the same, and the users may have authored e.g. tests which rely on an executable's module name.
116+
settings[.PRODUCT_MODULE_NAME] = mainModule.c99name
116117
settings[.PRODUCT_BUNDLE_IDENTIFIER] = "\(self.package.identity).\(product.name)"
117118
.spm_mangledToBundleIdentifier()
118119
settings[.SWIFT_PACKAGE_NAME] = mainModule.packageName
@@ -415,7 +416,7 @@ extension PackagePIFProjectBuilder {
415416
case .executable, .snippet:
416417
// For executable targets, we depend on the *product* instead
417418
// (i.e., we infuse the product's main module target into the one for the product itself).
418-
let productDependency = modulesGraph.allProducts.only { $0.name == moduleDependency.name }
419+
let productDependency = modulesGraph.allProducts.only { $0.mainModule?.name == moduleDependency.name }
419420
if let productDependency {
420421
let productDependencyGUID = productDependency.pifTargetGUID
421422
self.project[keyPath: mainModuleTargetKeyPath].common.addDependency(

Tests/CommandsTests/TestCommandTests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,31 @@ struct TestCommandTests {
317317
}
318318
}
319319

320+
@Test(
321+
.IssueWindowsLongPath,
322+
.tags(
323+
.Feature.TargetType.Executable,
324+
),
325+
arguments: SupportedBuildSystemOnAllPlatforms, BuildConfiguration.allCases,
326+
)
327+
func testableExecutableWithDifferentlyNamedExecutableProduct(
328+
buildSystem: BuildSystemProvider.Kind,
329+
configuration: BuildConfiguration,
330+
) async throws {
331+
try await withKnownIssue(isIntermittent: true) {
332+
try await fixture(name: "Miscellaneous/TestableExeWithDifferentProductName") { fixturePath in
333+
let result = try await execute(
334+
["--vv"],
335+
packagePath: fixturePath,
336+
configuration: configuration,
337+
buildSystem: buildSystem,
338+
)
339+
}
340+
} when: {
341+
.windows == ProcessInfo.hostOperatingSystem
342+
}
343+
}
344+
320345
@Test(
321346
.tags(
322347
.Feature.TargetType.Executable,

0 commit comments

Comments
 (0)