# The README links to apple/swift, the toolchain options are non-exhaustive, and 6.3 is still patched

> Swift is a system programming language whose compiler, standard library and runtimes live in one CMake-driven repository. The parts of the README that matter to anyone who builds it are the unglamorous ones. Two different scripts are involved, the option list is declared non-exhaustive, debug symbols are a separate archive you have to remember to install, and a changed Xcode leaves a stale cache that only --clean or --reconfigure clears.

**swiftlang/swift** — Swift is a high-performance system programming language with clean modern syntax, memory safety by default, and seamless interop with C and Objective-C code.

- Repository: https://github.com/swiftlang/swift
- Website: https://swift.org
- Stars: 70,407 · Forks: 10,823
- Language: Swift
- License: Apache-2.0
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/swiftlang-swift

## The README links to apple/swift while the repository is swiftlang/swift

The build instructions point at the old organisation in several places. The link for `build-toolchain` is written as a path under `github.com/apple/swift/blob/main/utils/build-toolchain`, and the pre-submission testing link points at `github.com/apple/swift/blob/main/docs/ContinuousIntegration.md`. The repository itself is `swiftlang/swift`.

These are redirecting links, so the instruction is still usable, and the project has kept them working. The reason to notice is that it dates the document. A README whose prose is current but whose URLs are from the previous home of the project is a file that gets edited in patches rather than rewritten, and that tells you how much to trust the rest of it as a description of the current layout.

The compiler's internal design documentation is referenced differently, as a path relative to the repository at `/docs/README.md`, and the contributor guides are the same: a first pull request guide, a getting started guide and an FAQ, all under `docs/HowToGuides`. So the README is an index that fans out into six or seven documents rather than a self-contained build description, and the entry point you want depends on which of three jobs you have: fixing the compiler, building the compiler once, or producing a distributable toolchain.

## Two scripts, and the invocation path assumes a directory named swift

Building a toolchain runs a script the README reaches as `./swift/utils/build-toolchain $BUNDLE_PREFIX`. The leading `swift/` is not part of the repository, which is checked out into a directory that the invocation assumes is named `swift`. Run it from the wrong place and the path does not resolve, which is the first thing that bites someone following the line literally.

`$BUNDLE_PREFIX` is a string prepended to the build date to form the bundle identifier in the toolchain's `Info.plist`. The example given is that a prefix of `com.example` produces a toolchain whose identifier is `com.example.YYYYMMDD`. The output lands in the directory you invoked the script from, as a file named `swift-LOCAL-YYYY-MM-DD-a-osx.tar.gz`.

The second script appears in the failure section rather than the build section, where the advice for a changed Xcode is to pass `--clean` or `--reconfigure` to `build-script`. So there are two tools: `build-toolchain` bundles and packages, and `build-script` is the underlying CMake-driven build. The README documents the first in detail and the second only through the two flags you reach for when something has gone wrong, which is the right way round for a build script and the wrong way round for someone who wants to configure a build deliberately.

## The option list is declared non-exhaustive, so --help is the only reference

The README introduces its option list with an explicit disclaimer that it is a non-exhaustive set of useful options, and then closes by saying more options may be added over time and that you should pass `--help` to `build-toolchain` to see the full set.

That sentence is doing real work and is easy to skim past. Four options are named, and all four are off by default: `--dry-run` for a dry run build, `--test` to test the toolchain after it has been compiled, `--distcc` to distribute the C++ part of the build, and `--sccache` to cache more C++ build artifacts for subsequent compiler builds.

Two of those are about the C++ specifically, which tells you where the time goes. Distributing compilation and caching compiled artefacts are both aimed at the same large C++ component, not at the Swift sources. The remaining two change what the script verifies and whether it builds at all, which means a run with no options is a plain build that does not check its own output.

The consequence is that a script wrapping this tool cannot be written from the README alone. Any automation that needs to know whether a step exists, or to pass something the documentation has not caught up with, has to shell out to `--help` and parse the result, and has to tolerate the list growing between runs.

## Both --test and --sccache default to off, so a local toolchain is unverified

The defaults compose into a specific and slightly surprising position. Because `--test` is off by default, a toolchain produced by a plain invocation is compiled and packaged but never exercised. You get an archive, and whether the compiler in it works is something you discover afterwards by using it.

Because `--sccache` is also off by default, the second build of the compiler starts from scratch. The option exists to cache more C++ build artifacts so that subsequent builds are faster, which matters because the first build is dominated by C++ compilation and the second build is dominated by nothing you can reuse unless the cache is on.

So the out-of-the-box behaviour is the slowest configuration with the least verification in it. That is a defensible default for a CI script that has its own verification stage elsewhere, and the README does say the script is what swift.org's CI uses to produce snapshots, which is the context those defaults were chosen for. It is a poor default for a person building once on a laptop.

The practical advice is short. Pass `--test` if you want to know the toolchain works, and pass `--sccache` before you build a second time rather than after. Both are documented; the only thing the README does not do is tell you that omitting them is the slow path.

## Debug symbols are a separate archive, and a crash without them gives you nothing

Alongside the toolchain archive, the script generates a second one containing debug symbols. The README says it can be installed over the main archive, and that its purpose is allowing symbolication of any compiler crashes. The filename follows the same pattern with `-symbols` inserted: `swift-LOCAL-YYYY-MM-DD-a-osx-symbols.tar.gz`.

The installation commands are given as a pair, with the `sudo` variant writing to the system location and the plain variant writing to the user location:

```sh
$ sudo tar -xzf swift-LOCAL-YYYY-MM-DD-a-osx-symbols.tar.gz -C /
$ tar -xzf swift-LOCAL-YYYY-MM-DD-a-osx-symbols.tar.gz -C ~/
```

Nothing in the README flags this as optional, and it is not, for anyone who will debug the compiler. A release toolchain is stripped, so a crash in it gives you an address and a module and no function names. The symbol archive is what turns that into a stack trace you can act on, and it is only useful if it is already installed, because recovering it after the crash means rebuilding.

The same pair of commands installs the main archive, and both steps then end with selecting the local toolchain in Xcode through `Xcode->Toolchains`. That last part is a manual UI action, which is the only step in this whole procedure that is not a command you can paste.

## A changed Xcode leaves a stale CMake cache, cleared by --clean or --reconfigure

The failure section is short and unusually specific about the most common cause. It says to work through the troubleshooting section of the getting started guide, to make sure you are using the correct release of Xcode, and then, if you have changed Xcode versions and still hit errors that look related to the Xcode version, to pass `--clean` to `build-script`.

The second half of the answer is the cheaper one. When a new version of Xcode is released, you can update your build without recompiling the entire project by passing `--reconfigure` to `build-script`.

Both flags exist because the build is a configured CMake project, and a configured project caches the configuration that produced it. Change the compiler toolchain underneath it and the cache still describes the old one, so the build either fails with errors that name the old Xcode or, worse, succeeds using what it recorded rather than what you installed. The two flags separate the two costs: `--reconfigure` re-reads the configuration and keeps your object files, and `--clean` discards enough that you are back to a known state.

For a language whose compiler is a C++ build of this size, choosing wrongly is expensive. `--reconfigure` is the right first attempt after an Xcode upgrade, and the README's ordering implies that, by offering the full clean only once the cheaper option has not worked.

## The compiler is written in Swift, and there are three separate test layers

The tree explains the shape of the project better than the prose does. `SwiftCompilerSources` holds the compiler, which is to say the compiler is itself written in Swift, and `stdlib`, `lib`, `include` and `Runtimes` hold the standard library, the core library, public headers and the platform runtimes. `bindings`, `tools` and `utils` hold the surrounding tooling, with `utils` being where `build-toolchain` lives.

What is worth counting is the test surface. There are three separate top-level directories: `test`, `unittests` and `validation-test`. A change can pass one and still fail another, and the README does not explain the division because the division is documented elsewhere, in the continuous integration document it links to for the pre-submission testing requirement.

The supporting files point the same way. There is a `Brewfile` for bootstrapping a macOS development machine through Homebrew, a `.flake8` for the Python side of the build and bootstrap scripts, `.clang-format` and `.clang-tidy` for the C++ sources, `benchmark` for performance work, `apinotes` for annotating APIs, `localization` for diagnostic messages, `CODE_OWNERS.TXT` for ownership, and a `CHANGELOG.md` at the root.

It is a repository with a large surface and a small README, which is the correct balance for a language implementation and also the reason the README points at seven other documents rather than pretending to be complete.

## Conclusion

Swift suits someone who wants to work on the compiler, the standard library or the runtimes and is prepared to treat a local build as a multi-gigabyte C++ compile rather than a package install, since that is what the repository sets up. It does not suit someone looking for a quick way to get the language onto a machine, because the README documents building rather than installing and defers the how to a separate guide. Before you start, decide which line you are on, because 6.4.0 shipped on 2026-09-15 while 6.3.2 and 6.3.3 were patched in June, and both lines were receiving work. Then budget for the two steps people forget: pass --help to build-toolchain rather than trusting the README, and install the symbols archive, because without it a compiler crash gives you an address and no function name.

## FAQ

### how to install swift

The README does not give an install command; it documents building. Installing a toolchain means running build-toolchain with a bundle prefix, unpacking the resulting tarball into /Library/Developer/Toolchains/ or ~/Library/Developer/Toolchains/, and then selecting it in Xcode under Xcode->Toolchains. For just using the language, the README points to swift.org for documentation and to a getting started guide under docs/HowToGuides.

### how to install swift on mac

On macOS you build a toolchain and unpack it into one of two locations. The archive is swift-LOCAL-YYYY-MM-DD-a-osx.tar.gz, and there is a matching -symbols archive for debugging compiler crashes. After unpacking, the toolchain is chosen through the Xcode->Toolchains menu, which is a manual step rather than a command.

### how to use swift code

The README describes the language rather than a tutorial. It calls Swift a high-performance system programming language that is memory-safe by default, gives direct access to existing C and Objective-C code and frameworks, and notes that Swift is not itself a C-derived language. It packages flow control, data structures and functions, with objects, protocols, closures and generics as higher-level constructs, and uses modules instead of headers.

### how to use swift

For learning the language, the README points to the documentation on swift.org, and for the compiler's internal design to a documentation index in the repository's docs directory. For working on it, it separates three jobs: contributing compiler fixes, building the compiler as a one-off, and building a toolchain as a one-off, each with its own guide under docs/HowToGuides, plus an FAQ for common questions.

## Sources

- [Official documentation](https://swift.org)
- [Official README](https://github.com/swiftlang/swift#readme)
- [Project repository](https://github.com/swiftlang/swift)
- [Release notes](https://github.com/swiftlang/swift/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/swiftlang-swift
