xcdo automatically adds necessary or helpful compiler flags to swiftc and clang. Inspired by xcrun, which sets essential environment variables. xcdo is intended for exploratory use, not from a build system.
Use xcdo instead of xcrun when running swiftc or clang. It's possible to alias xcrun to xcdo.
Use the -### flag to show, but not execute, the underlying xcrun command. For example:
xcdo -### -sdk iphoneos clang++ -c source.cppwill print:
xcrun -sdk iphoneos clang++ -target arm64-apple-ios13.0 -std=c++17 -Wall -c source.cppxcrun sets the correct sysroot/sdk, but not the correct target triple. Both swiftc and clang assume compilation for the current host, which for macOS is x86_64. When building for other SDKs, the correct target is needed as well.
xcdo determines which target -triple to use based on the -sdk flag. The mapping is:
| SDK | xcrun |
xcdo |
|---|---|---|
iphoneos |
x86_64-apple-ios13.0.0 |
arm64-apple-ios13.0 |
iphonesimulator |
x86_64-apple-ios13.0.0-simulator |
x86_64-apple-ios13.0-simulator |
macosx |
x86_64-apple-macosx10.14.0 |
x86_64-apple-macosx10.14 |
Using clang -v or swiftc -v prints the underlying commands being run. These command lines often contain temp files, but they are deleted by at the end of the command. xcdo adds -save-temps whenever -v is given, to allow the temp files to be inspected.
Unless -whole-module-optimization is used, xcdo adds -enable-batch-mode.
If -emit-module-interface is specified, then -enable-library-evolution is added if not present, since it is required to produce .swiftinterface files.
Swift incremental compilation requires a JSON output-file-map. When using -incremental, xcdo will generate an output-file-map if none is given. Also, -driver-show-incremental is added.
See Swift's documentation Driver: Incremental Builds for details on swift incremental builds.
clang defaults to -std=c++98, which is quite old. xcdo defaults to -std=c++17 when no -std flag is used.
xcdo adds -Wall when no other -W flag is used.
clang does not enable ARC by default. xcdo enables ARC when compiling objc/objc++ sources by adding -fobjc-arc.
Generated assembly can be noisy. Running clang -S with xcdo will add -fomit-frame-pointer and -fno-unwind-tables. Thanks to Greg Parker for sharing this tip https://twitter.com/gparker/status/1147723601656729600.