Swift error "Hashbang line is allowed only in the main file"

Viewed 41

I wish to create an interpreted Swift command-line utility. Thus, in Xcode 13.1, I create a new project, and use the template "Command Line Tool". This results in an empty project with a single file, called main.swift.

I want to distribute this command-line utility as a single file, so having the "main.swift" name isn't useful. I rename it to MyCommandlineProject.swift, then add the hashbang line on top, and add code that marks it as being the main file. The contents now look as follows:

#!/usr/bin/swift

import Foundation

@main
struct CLI {
    static func main() {
        print("Hello, World!")
    }
}

Despite the @main annotation, I still get the following compiler error:

Hashbang line is allowed only in the main file

Why?

1 Answers

If you are just writing a script you don't need any of that @main stuff. @main is really only for when you have multiple files that you need to compile into an executable.

For a script, like you are writing, you can just add top level functions and they will get called just as if you were writing in a playground.

#!/usr/bin/swift

import Foundation

print("Hello, World!")

You can execute the script with:

chmod 744 scriptName.swift
./scriptName.swift

Or

swift scriptName.swift

Now if you have multiple files, let's call them First.swift:

import Foundation

@main enum First {
    static func main() {
        print("First.main")
        Second.execute()
    }
}

And Second.swift:

import Foundation

enum Second {
    static func execute() { print("Second.execute") }
}

You have to prefix your entry point with @main like we did for First. You also have to give it a static main() method.

First you have to compile:

swiftc -o awesome First.swift Second.swift

Then to run:

./awesome
Related