Building non-UI programs, e.g., command-line tools, servers, etc

I wanted to build some command line utilities in Swift and started by following the Build a Command-line Tool tutorial. This is working great, I am using it to write nice little tools and to learn Swift better in the process.

What I find not so enjoyable is how difficult it is to discover documentation in order to understand the process and how to control it as I wish. For example, I struggled for close to an hour to find out how to build an optimized executable and how to find it—in case I wanted to save it and use it—on my computer. I eventually found the answer from some YouTube tutorial but even after knowing what to search for, am not able to find a lot of quality information.

Is this by design (perhaps because Swift is primarily intended for UI work) or simply an artifact of the young age of the language and its ecosystem? Do people just suck it up and struggle to accumulate these kinds of experiences, or, am I simply missing some good documentation and other great resources out there which are not the automatically generated Apple API documentation?

If anyone has advice or pointers, I'll gladly listen :slight_smile:

2 Likes

i doubt that Swift is “designed” to be hard to learn. there is no single entity responsible for teaching Swift.

a great resource for learning about Swift in non-GUI contexts is Swift on Server by @Joannis_Orlandos and @tiborbodecs . it is mostly geared towards server use cases, but it also has a lot of great information for developing Swift on Linux and non-GUI Swift more generally.

for automatically-generated API documentation, you might check out Swiftinit which contains API docs for many of the more popular Linux packages.

4 Likes

I personally think a lot of these frustrations and missing docs stem from us (maintainers) not knowing what's unclear or missing.

The two questions you described above are so intimately familiar to me, that it hasn't crossed my mind in 7 years that someone might not know how to do this, or where to find this.

5 Likes

The Command Line tutorial you mention is very good, with focus on using Swift Package Manager and building from the command line. For a beginner with Swift I think this start a bit too far. My advice for beginner that want exploring Swift with CLI apps is using Xcode, creating a project by choosing the Command Line Tool in the template window:

After from main.swift you enter the following code:

import Foundation

print("Hello, World!")

let cliArguments = CommandLine.arguments

print(cliArguments)

// do wathever you want using the command line arguments

exit(0)

Build the app.

To run the app in the terminal, first go to the folder where the compiled binary reside:

Open the terminal from this location.

When in the terminal run your app passing some arguments:

From there you can experiment a lot with any kind of Swift code including adding Packages from Xcode. Days, weeks later you can continue your learning with Swift PM and building from the command line instead of Xcode, porting to Windows, Linux, using VS Code on Windows/Linux etc..

Hoping this can help.

2 Likes

Generally command-line programs include their own help. This is true for Swift toolchain commands as well.

For instance, swift package help will tell you about the -c flag:

> swift package help
OVERVIEW: Perform operations on Swift packages

SEE ALSO: swift build, swift run, swift test

USAGE: swift package <options> <subcommand>

OPTIONS:
[snip]
  -c, --configuration <configuration>
                          Build with configuration (default: debug)

The "See also" section directs us to the swift build command, whose help page informs us about the --show-bin-path flag:

> swift build -help
OVERVIEW: Build sources into binary products

SEE ALSO: swift run, swift package, swift test

USAGE: swift build <options>

OPTIONS:
[snip]
  --show-bin-path         Print the binary output path

That being said, the "options" sections are very large and not well organised. We could do a better job by grouping the options in to sections and arranging those sections such that more broadly-useful options feature towards the top of the list (e.g. the -c option I mentioned above is buried near the bottom of the list, under flags about caching, verbose output, package registries, and netrc files -- but IMO debug vs release build is a more fundamental decision that should be much nearer the top).

I could also imagine that --show-bin-path is useful enough to include in the swift package command directly.

Perhaps the tutorial should also mention the help options available directly from the CLI tools.

This is all useful feedback. You certainly do have a point that it isn't very easy to discover this stuff.

3 Likes

Thanks all, great replies and tips.

Perhaps I was a bit unclear, my frustration is not so much about understanding Swift. I've found plenty of high quality resources on the language itself—incl. the official book/reference, other published books and WWDC tutorials—and rarely find myself needing help or more docs.

What I found missing was the more comprehensive picture incl. the engineering process that goes into building various kinds of programs. Being more of a command line type of person (call me old-fashioned but I am much faster on it than with the mouse) I wanted to explore this direction more deeply.

For example, after I found about PackageDescription, Package, and BuildConfiguration I wanted to dig in a little deeper into them and explore but I got nowhere—can't even import PackageDescription in a regular swift file and BuildConfiguration seems to be intended to be an opaque type in the first place. I was curious if I could have different/custom BuildConfigurations and should I even want to or care or just stick with the predefined ones but it seems that this is not possible at the moment (or I just couldn't find how).

Cheers,

1 Like

SwiftPM itself is just a package, and if you really wanted to, you could depend on the SwiftPM git repo and write your own build system using SwiftPM as a base layer.

That is a question.

You are lucky then :)

How to save and use the compiled executable on a computer where the Swift compiler is not installed may be tricky, because you need to copy not only the executable file, but also all its runtime dependencies (dynamic libraries), which are parts of the Swift compiler. The more things you import (Foundation, etc.) the more files you need to redistribute. A seemingly small executable may require ~20MB of runtime libraries.

swift build --static-swift-stdlib ?

1 Like

Does not work on all platforms.

2 Likes

On Windows the Swift redistributables are located in: C:\Users\youruser\AppData\Local\Programs\Swift\Runtimes\5.10.0\usr\bin

Create an MyApp folder, copy in the folder those Swift redistributable DLLs, your executable, your own DLLs and the required Microsoft redistributables like vcruntime140.dll, vccorlib140.dll etc.. Running your app, if a DLL is missing a message will tell you.

Indeed, for some (now historical) reason the resulting executable is buried in an obscure subfolder in a hidden .build folder.

2 Likes

I have those same questions...

Out of curiousity are you only using Swift Package Manager to compile scaffold your programs? You don't have to, if you're used to more manual build processes, which it sounds like you might be?

  • swiftc *swift -o myappname
  • swiftc `find . -name "*.swift" -maxdepth 1` -o myappname (for subfolders)

Has been handy for me to sweep in a bunch of swift files into the same batch. Although I haven't pushed this avenue too far. Haven't tried using swiftc in a Makefile, for example. I think Swift is more of a CMake community anyway?

Also you can put a #!/usr/bin/env swift at the top of the file and just chmod +x and run (./myscript.swift) But again, don't see a lot of examples.

On my list of things to do soon is learn about compiling Swift directly with CLang and NOT swiftc (yes swiftc contains CLang, but idk, waves fingers in LLVM??)? Is that even a thing? (in my bookmarks: Cross-compilation using Clang — Clang 19.0.0git documentation )

But I've seen very few articles/videos that cover hand compiling. It doesn't seem like people super do that in general? Or maybe I'm just not looking for resources in the right places?

For myself I'd love an XCode & Package Manager free build tools overview, that then maybe went into how Package Manager hooks into all that. While all things are discoverable with enough --help, I'd would sure watch the hell out of that WWDC session.