/commands/swift/swift-build-release
swift build -c release: build an optimized Swift package
- tool
- Swift
- versions
- Swift 5.x – 6.x
- os
- macos, linux, windows
swift build -c release compiles a Swift package with the release configuration: optimizations on (-O) and whole-module optimization, instead of the default debug build (-Onone, debug information, testability). The products land in .build/release/; run the executable from there or with swift run -c release. Use it for benchmarks, deployment and anything you ship.
Build and run
swift build -c release
swift build -c release --show-bin-path
.build/release/MyTool --help
swift run -c release MyTool --help--show-bin-path prints the folder that holds the built products, which is handy in scripts and Dockerfiles. swift run builds first if needed and then runs the named executable product, passing the rest of the arguments to it.
Debug vs release
The SwiftPM documentation lists the flags each configuration uses:
| Debug (default) | Release (-c release) | |
|---|---|---|
| Swift flags | -Onone, -g, -enable-testing | -O, -whole-module-optimization |
| C targets | -O0, -g | -O2 |
| Output folder | .build/debug | .build/release |
| @testable import | Works | Needs -Xswiftc -enable-testing |
| Use for | Development, debugging, tests | Benchmarks, deployment, distribution |
Useful options
| Option | Effect |
|---|---|
| -c release / --configuration release | Optimized build |
| --product NAME | Build only one product |
| --target NAME | Build only one target |
| --static-swift-stdlib | Link the Swift standard library statically |
| -Xswiftc FLAG | Pass a flag to every Swift compiler invocation (for example -Xswiftc -enable-testing) |
| -Xcc FLAG / -Xlinker FLAG | Pass flags to the C compiler or the linker |
| --jobs N | Limit parallel build jobs |
| --scratch-path DIR | Use another build folder instead of .build |
Pitfalls
- Comparing performance in debug. Debug builds can be many times slower than release builds; never benchmark
swift buildoutput without-c release. - Separate build folders. Debug and release keep their own artifacts; switching configurations does not reuse the other one's objects, so the first release build takes a while.
- Linux runtime libraries. A release binary built without
--static-swift-stdlibstill needs the Swift runtime libraries on the target machine; copy them or link statically. - Docker images. Building in a
swift:image and copying.build/release/NAMEinto a slim image is the pattern the Swift server guides describe; use--show-bin-pathinstead of hard-coding the triple folder. - Cargo users. The equivalent in Rust is cargo build --release.
Confirm it worked
ls "$(swift build -c release --show-bin-path)" lists the built executables and libraries, and running the binary from there executes the optimized build.
FAQ
Where is the binary after swift build -c release?
In the release folder under .build, at .build/release/NAME (a path that includes the target triple, linked from .build/release). swift build -c release --show-bin-path prints the exact folder.
Why are my tests not built with -c release?
Release builds do not enable testability, so @testable import fails. Build or test in release with -Xswiftc -enable-testing, as the Swift server guide shows for sanitizer runs.
How do I make a statically linked Linux binary?
Add --static-swift-stdlib to link the Swift standard library statically, so the binary runs on machines without a Swift runtime installed. Fully static binaries use the Static Linux SDK with --swift-sdk.