Open compnerd opened 4 years ago
@swift-ci create
It looks like compilation is failing whenever the compiler's in single-file mode. Using the two attached source files, I get this result from trying to compile just MyMain.swift
:
$ swiftc MyMain.swift
MyMain.swift:3:1: error: 'main' attribute cannot be used in a module that contains top-level code
@main
^
MyMain.swift:1:1: note: top-level code defined in this source file
// @main attribute test
^
When I add Empty.swift
, the issue goes away:
$ swiftc MyMain.swift Empty.swift
(compiles without issue)
To make this work, you can tell the compiler to parse the file as a library instead of in single-file mode with the -parse-as-library
flag:
$ swiftc -parse-as-library MyMain.swift
Comment by Josh Wright (JIRA)
Any updates to this? Hitting this issue as well when writing a single file script.
Nate's workaround works, but would be great to have this work out of the box (was using it indirectly through https://github.com/mxcl/swift-sh so it wasn't apparent how to update the compiler flags).
Comment by Eneko Alonso (JIRA)
This seems to still be an issue for new Swift 5.5 packages containing a main.swift file.
Steps to reproduce:
{{
@main
struct Program {
static func main() {
print("Hello, world!")
}
}
}}
4. swift run
Adding a second file does not seem to fix the issue:
{{
func hello() {
print("Hello, world!")
}
}}
2. Update `main.swift` as follows:
{{
@main
struct Program {
static func main() {
hello()
}
}
}}
3. swift run
Renaming `main.swift` to something else (eg. `Program.swift`) solves the issue, whether there are only one file or more.
{{
func hello() {
print("Hello, world!")
}
@main
struct Program {
static func main() {
hello()
}
}
}}
3. swift run
I can confirm the issue for this example where I import a cooperating module:
// Swift version 5.6 (swift-5.6-RELEASE)
// Target: arm64-apple-macosx12.0
import Foundation
import SwiftUI
import HelloCore
@main
struct HelloApp: App {
var body: some Scene {
WindowGroup {
HelloView().onAppear {
print("loaded")
signal(SIGINT) { _ in
print("exit")
exit(EXIT_SUCCESS)
}
}
}
}
}
The renaming solution works. However, you may then see swift build
errors such as:
'Hello': error: executable product 'Hello' expects target 'Hello' to be executable;
an executable target requires a 'main.swift' file
You can fix that by changing the .target
in your Package.swift
to .executableTarget
.
Trying to use this example for using raw nio:https://theswiftdev.com/swiftnio-tutorial-the-echo-server/ its only from 3 months ago, but I the newest info I've found. seems the renaming worked for me was well.
This issue seems very old but I'd like to chime in that it doesn't seem fixed at all in Swift 5.9. See https://github.com/apple/swift-getting-started-cli/issues/3 - I hit the bug midway through the "getting started" tutorial for a command line program.
Studying Apple's tutorial Getting Started with ArgumentParser, perhaps this is expected behaviour. See:
Note The Swift compiler uses either the type marked with @main or a main.swift file as the entry point for an executable program. You can use either one, but not both — rename your main.swift file to the name of the command when you add @main. In this case, rename the file to Count.swift.
Studying Apple's tutorial Getting Started with ArgumentParser, perhaps this is expected behaviour.
That was my conclusion as well, but then you get a different error if you don't have any main.swift files:
executable product 'currgen' expects target 'Generator' to be executable; an executable target requires a 'main.swift' file
@ubunatic had the actual fix in his comment above: executable target
.
The problem is that Getting Started with ArgumentParser has target
, so that example code actually fails to compile. But the example in ArgumentParser's README does use executableTarget
.
That seems like a different issue. First, the tutorial should be updated. Second, the error could probably say something that would help direct the person to using executableTarget
.
Which repo would be the right place to log an issue about the error message?
This is frustrating for someone writing tutorials about Swift development using an asynchronous API for both Apple platforms and Linux, because:
swift package init
, they get a source file named "main.swift".It would be nice if whoever needs to fix this would just do it. I can't imagine it being that hard to fix...
This still is an issue with release 5.10.1.
I tried following this tutorial, and it failed.
I tried following the same by never doing swift run
with the main.swift, and only ever building with the MyCLI.swift file and still get the error:
...\mycli\Sources\MyCLI.swift:3:1: error: 'main' attribute cannot be used in a module that contains top-level code
@main
^
...\mycli\Sources\MyCLI.swift:1:1: note: top-level code defined in this source file
import Figlet
^
...\mycli\Sources\MyCLI.swift:1:1: note: pass '-parse-as-library' to compiler invocation if this is intentional
import Figlet
^
...\mycli\Sources\MyCLI.swift:3:1: error: 'main' attribute cannot be used in a module that contains top-level code
@main
^
...\mycli\Sources\MyCLI.swift:1:1: note: top-level code defined in this source file
import Figlet
^
...\mycli\Sources\MyCLI.swift:1:1: note: pass '-parse-as-library' to compiler invocation if this is intentional
import Figlet
^
error: fatalError
OK so it looks like I need to use -XSwiftc -parse-as-library
in order to be able to do swift run
.
OK so it looks like I need to use
-XSwiftc -parse-as-library
in order to be able to doswift run
.
Ran into the same issue in the same tutorial as @ayaen , Swift 5.10.1 on WIndows. This worked but it was -Xswiftc
with a lowercase s
.
Attachment: Download
Additional Detail from JIRA
| | | |------------------|-----------------| |Votes | 16 | |Component/s | | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: d99a1a03d2003d32b1bfd6a2ae65a2fais duplicated by:
Issue Description:
There seems to be a recent regression with comment blocks and functions being treated as top level code which prevents the use of `@main`.