Skip to content

Commit 5275f37

Browse files
authored
Revert "improve heuristics for @main support (#5678)" (#5685)
This reverts commit ea24981.
1 parent ea24981 commit 5275f37

File tree

2 files changed

+23
-64
lines changed

2 files changed

+23
-64
lines changed

Sources/Build/BuildPlan.swift

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -626,26 +626,21 @@ public final class SwiftTargetBuildDescription {
626626
public let isTestDiscoveryTarget: Bool
627627

628628
/// True if this module needs to be parsed as a library based on the target type and the configuration
629-
/// of the source code
629+
/// of the source code (for example because it has a single source file whose name isn't "main.swift").
630+
/// This deactivates heuristics in the Swift compiler that treats single-file modules and source files
631+
/// named "main.swift" specially w.r.t. whether they can have an entry point.
632+
///
633+
/// See https://bugs.swift.org/browse/SR-14488 for discussion about improvements so that SwiftPM can
634+
/// convey the intent to build an executable module to the compiler regardless of the number of files
635+
/// in the module or their names.
630636
var needsToBeParsedAsLibrary: Bool {
631-
switch self.target.type {
637+
switch target.type {
632638
case .library, .test:
633639
return true
634640
case .executable:
635-
// This deactivates heuristics in the Swift compiler that treats single-file modules and source files
636-
// named "main.swift" specially w.r.t. whether they can have an entry point.
637-
//
638-
// See https://bugs.swift.org/browse/SR-14488 for discussion about improvements so that SwiftPM can
639-
// convey the intent to build an executable module to the compiler regardless of the number of files
640-
// in the module or their names.
641-
if self.toolsVersion < .v5_5 || self.sources.count != 1 {
642-
return false
643-
}
644-
// looking into the file content to see if it is using the @main annotation which requires parse-as-library
645-
// this is not bullet-proof since theoretically the file can contain the @main string for other reasons
646-
// but it is the closest to accurate we can do at this point
647-
let content: String = self.sources.first.flatMap({ try? self.fileSystem.readFileContents($0) }) ?? ""
648-
return content.contains("@main")
641+
guard toolsVersion >= .v5_5 else { return false }
642+
let sources = self.sources
643+
return sources.count == 1 && sources.first?.basename != "main.swift"
649644
default:
650645
return false
651646
}

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 12 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,41 +1206,15 @@ final class BuildPlanTests: XCTestCase {
12061206

12071207
func testParseAsLibraryFlagForExe() throws {
12081208
let fs = InMemoryFileSystem(emptyFiles:
1209-
// executable has a single source file not named `main.swift`, without @main.
1209+
// First executable has a single source file not named `main.swift`.
12101210
"/Pkg/Sources/exe1/foo.swift",
1211-
// executable has a single source file named `main.swift`, without @main.
1211+
// Second executable has a single source file named `main.swift`.
12121212
"/Pkg/Sources/exe2/main.swift",
1213-
// executable has a single source file not named `main.swift`, with @main.
1214-
"/Pkg/Sources/exe3/foo.swift",
1215-
// executable has a single source file named `main.swift`, with @main
1216-
"/Pkg/Sources/exe4/main.swift",
1217-
// executable has multiple source files.
1218-
"/Pkg/Sources/exe5/bar.swift",
1219-
"/Pkg/Sources/exe5/main.swift"
1213+
// Third executable has multiple source files.
1214+
"/Pkg/Sources/exe3/bar.swift",
1215+
"/Pkg/Sources/exe3/main.swift"
12201216
)
12211217

1222-
try fs.writeFileContents(AbsolutePath("/Pkg/Sources/exe3/foo.swift")) {
1223-
"""
1224-
@main
1225-
struct Runner {
1226-
static func main() {
1227-
print("hello world")
1228-
}
1229-
}
1230-
"""
1231-
}
1232-
1233-
try fs.writeFileContents(AbsolutePath("/Pkg/Sources/exe4/main.swift")) {
1234-
"""
1235-
@main
1236-
struct Runner {
1237-
static func main() {
1238-
print("hello world")
1239-
}
1240-
}
1241-
"""
1242-
}
1243-
12441218
let observability = ObservabilitySystem.makeForTesting()
12451219
let graph = try loadPackageGraph(
12461220
fileSystem: fs,
@@ -1253,8 +1227,6 @@ final class BuildPlanTests: XCTestCase {
12531227
TargetDescription(name: "exe1", type: .executable),
12541228
TargetDescription(name: "exe2", type: .executable),
12551229
TargetDescription(name: "exe3", type: .executable),
1256-
TargetDescription(name: "exe4", type: .executable),
1257-
TargetDescription(name: "exe5", type: .executable),
12581230
]),
12591231
],
12601232
observabilityScope: observability.topScope
@@ -1268,30 +1240,22 @@ final class BuildPlanTests: XCTestCase {
12681240
observabilityScope: observability.topScope
12691241
))
12701242

1271-
result.checkProductsCount(5)
1272-
result.checkTargetsCount(5)
1243+
result.checkProductsCount(3)
1244+
result.checkTargetsCount(3)
12731245

12741246
XCTAssertNoDiagnostics(observability.diagnostics)
12751247

1276-
// single source file not named main, and without @main should not have -parse-as-library.
1248+
// Check that the first target (single source file not named main) has -parse-as-library.
12771249
let exe1 = try result.target(for: "exe1").swiftTarget().emitCommandLine()
1278-
XCTAssertNoMatch(exe1, ["-parse-as-library"])
1250+
XCTAssertMatch(exe1, ["-parse-as-library"])
12791251

1280-
// single source file named main, and without @main should not have -parse-as-library.
1252+
// Check that the second target (single source file named main) does not have -parse-as-library.
12811253
let exe2 = try result.target(for: "exe2").swiftTarget().emitCommandLine()
12821254
XCTAssertNoMatch(exe2, ["-parse-as-library"])
12831255

1284-
// single source file not named main, with @main should have -parse-as-library.
1256+
// Check that the third target (multiple source files) does not have -parse-as-library.
12851257
let exe3 = try result.target(for: "exe3").swiftTarget().emitCommandLine()
1286-
XCTAssertMatch(exe3, ["-parse-as-library"])
1287-
1288-
// single source file named main, with @main should have -parse-as-library.
1289-
let exe4 = try result.target(for: "exe4").swiftTarget().emitCommandLine()
1290-
XCTAssertMatch(exe4, ["-parse-as-library"])
1291-
1292-
// multiple source files should not have -parse-as-library.
1293-
let exe5 = try result.target(for: "exe5").swiftTarget().emitCommandLine()
1294-
XCTAssertNoMatch(exe5, ["-parse-as-library"])
1258+
XCTAssertNoMatch(exe3, ["-parse-as-library"])
12951259
}
12961260

12971261
func testCModule() throws {

0 commit comments

Comments
 (0)