Skip to content

Commit 2ccaf04

Browse files
authored
SwiftPM complains about @main in non main.swift file when integrated driver is not enabled (#3546) (#3575)
One of several different code paths in BuildPlan.swift are taken depending on whether the integrated Swift driver is enabled, whether explicit modules are enabled, etc. In the non-integrated-driver case, the code path for adding a `-parse-as-library` when necessary wasn't taken. This moves that code to a more central place, and extends a unit test to test both single and multiple file Swift targets, which seems to trigger the difference in code paths. rdar://78080245 (cherry picked from commit e84fd1c)
1 parent c181446 commit 2ccaf04

File tree

7 files changed

+30
-21
lines changed

7 files changed

+30
-21
lines changed
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
// swift-tools-version:5.4
1+
// swift-tools-version:5.5
22
import PackageDescription
33

44
let package = Package(
55
name: "AtMainSupport",
66
products: [
7-
.executable(name: "ClangExec", targets: ["ClangExec"]),
8-
.executable(name: "SwiftExec", targets: ["SwiftExec"]),
7+
.executable(name: "ClangExecSingleFile", targets: ["ClangExecSingleFile"]),
8+
.executable(name: "SwiftExecSingleFile", targets: ["SwiftExecSingleFile"]),
9+
.executable(name: "SwiftExecMultiFile", targets: ["SwiftExecMultiFile"]),
910
],
1011
targets: [
11-
.executableTarget(name: "ClangExec"),
12-
.executableTarget(name: "SwiftExec"),
12+
.executableTarget(name: "ClangExecSingleFile"),
13+
.executableTarget(name: "SwiftExecSingleFile"),
14+
.executableTarget(name: "SwiftExecMultiFile"),
1315
]
14-
)
16+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@main
2+
struct MyProgram {
3+
static func main() {
4+
print("Hello, Swift.")
5+
}
6+
}

Sources/Build/BuildPlan.swift

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,11 @@ public final class SwiftTargetBuildDescription {
757757
}
758758
}
759759
}
760+
761+
// If the target needs to be parsed without any special semantics involving "main.swift", do so now.
762+
if self.needsToBeParsedAsLibrary {
763+
args += ["-parse-as-library"]
764+
}
760765

761766
// Only add the build path to the framework search path if there are binary frameworks to link against.
762767
if !libraryBinaryPaths.isEmpty {
@@ -809,10 +814,6 @@ public final class SwiftTargetBuildDescription {
809814
// FIXME: Eliminate side effect.
810815
result.append(try writeOutputFileMap().pathString)
811816

812-
if self.needsToBeParsedAsLibrary {
813-
result.append("-parse-as-library")
814-
}
815-
816817
if buildParameters.useWholeModuleOptimization {
817818
result.append("-whole-module-optimization")
818819
result.append("-num-threads")
@@ -849,10 +850,6 @@ public final class SwiftTargetBuildDescription {
849850
result.append("-experimental-skip-non-inlinable-function-bodies")
850851
result.append("-force-single-frontend-invocation")
851852

852-
if self.needsToBeParsedAsLibrary {
853-
result.append("-parse-as-library")
854-
}
855-
856853
// FIXME: Handle WMO
857854

858855
for source in target.sources.paths {
@@ -896,9 +893,6 @@ public final class SwiftTargetBuildDescription {
896893
// FIXME: Eliminate side effect.
897894
result.append(try writeOutputFileMap().pathString)
898895

899-
if self.needsToBeParsedAsLibrary {
900-
result.append("-parse-as-library")
901-
}
902896
// FIXME: Handle WMO
903897

904898
result.append("-c")

Tests/CommandsTests/BuildToolTests.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,22 @@ final class BuildToolTests: XCTestCase {
176176
fixture(name: "Miscellaneous/AtMainSupport") { path in
177177
let fullPath = resolveSymlinks(path)
178178
do {
179-
let result = try build(["--product", "ClangExec"], packagePath: fullPath)
180-
XCTAssert(result.binContents.contains("ClangExec"))
179+
let result = try build(["--product", "ClangExecSingleFile"], packagePath: fullPath)
180+
XCTAssert(result.binContents.contains("ClangExecSingleFile"))
181181
} catch SwiftPMProductError.executionFailure(_, let stdout, let stderr) {
182182
XCTFail(stdout + "\n" + stderr)
183183
}
184184

185185
do {
186-
let result = try build(["--product", "SwiftExec"], packagePath: fullPath)
187-
XCTAssert(result.binContents.contains("SwiftExec"))
186+
let result = try build(["--product", "SwiftExecSingleFile"], packagePath: fullPath)
187+
XCTAssert(result.binContents.contains("SwiftExecSingleFile"))
188+
} catch SwiftPMProductError.executionFailure(_, let stdout, let stderr) {
189+
XCTFail(stdout + "\n" + stderr)
190+
}
191+
192+
do {
193+
let result = try build(["--product", "SwiftExecMultiFile"], packagePath: fullPath)
194+
XCTAssert(result.binContents.contains("SwiftExecMultiFile"))
188195
} catch SwiftPMProductError.executionFailure(_, let stdout, let stderr) {
189196
XCTFail(stdout + "\n" + stderr)
190197
}

0 commit comments

Comments
 (0)