Difference between "swift" and "swift-frontend" binaries?

Hey folks, a question I've always wondered about:

After building the compiler and opening build/Xcode-DebugAssert/swift-macosx-x86_64/Debug/bin, I see both:

  • a swift-frontend binary
  • a swift alias, pointing to the swift-frontend binary

The swift command behaves differently from the swift-frontend command, despite being an alias. Why is that?

For example, I'm able to compile and run files using the swift command:

bin % ./swift test.swift  
Hello world

but not swift-frontend:

bin % ./swift-frontend test.swift
<unknown>:0: error: no frontend action was selected

even though swift appears to be a file alias pointing to the swift-frontend binary:

bin % ls -l swift
lrwxr-xr-x  1 cal  staff  14 Dec 19 13:17 swift -> swift-frontend

If swift is an alias of swift-frontend, why do they behave differently?


A related follow-up question: is there a swift-frontend invocation I can use that's equivalent to ./swift test.swift (e.g. build and run the given file)? It would be convenient to build-and-run this workflow through the Xcode swift-frontend scheme, but I've always had trouble figuring out what pass-on-launch arguments I should add to the scheme.

Thanks for answering my beginner questions :slight_smile:

1 Like

swift-frontend looks at the first argument—the command name—to decide whether to run as the frontend, the “old” driver, or one of a few other tools. This is a bit weird, but avoids having several binaries that contain basically the same code with different main functions. (The more straightforward way to do this would be to use a shared library, but tests with Clang/LLVM showed that there was a significant startup improvement from statically linking instead, which can really make a difference for compiling many simple files.)

You can see how the Swift compiler driver invokes the frontend by adding -v, including when using it as the “build-and-run” interpreter. I believe the equivalent frontend command has an -interpret flag, but really you should just check with -v.

4 Likes

This pointed me to ./swift-frontend -interpret test.swift, which is exactly what I was looking for.

Very helpful, thanks!

2 Likes