Skip to content

Commit 60a4af3

Browse files
committed
Add documentation about the compiler's standalone driver and its build procedure.
1 parent c2dc8e3 commit 60a4af3

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

docs/DebuggingTheCompiler.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ benefit of all Swift developers.
3636
- [Bisecting on SIL optimizer pass counts to identify optimizer bugs](#bisecting-on-sil-optimizer-pass-counts-to-identify-optimizer-bugs)
3737
- [Using git-bisect in the presence of branch forwarding/feature branches](#using-git-bisect-in-the-presence-of-branch-forwardingfeature-branches)
3838
- [Reducing SIL test cases using bug_reducer](#reducing-sil-test-cases-using-bug_reducer)
39+
- [Debugging the Compiler Build](#debugging-the-compiler-build)
40+
- [Build Dry Run](#build-dry-run)
41+
- [Debugging the Compiler Driver](#debugging-the-compiler-driver-build)
42+
- [Swift Compiler Driver F.A.Q](#swift-compiler-driver-f.a.q.)
43+
- [Building the compiler without using the standalone driver](#building-the-compiler-without-the-standalone-driver)
44+
- [Invoking the compiler without forwarding to the standalone driver](#invoking-the-compiler-without-forwarding-to-the-standalone-driver)
45+
- [Reproducing the Compiler Driver build steps](#reproducing-the-compiler-driver-build-steps)
46+
- [Installing the Compiler Driver](#installing-the-compiler-driver)
3947
- [Debugging Swift Executables](#debugging-swift-executables)
4048
- [Determining the mangled name of a function in LLDB](#determining-the-mangled-name-of-a-function-in-lldb)
4149
- [Manually symbolication using LLDB](#manually-symbolication-using-lldb)
@@ -807,6 +815,131 @@ reducing SIL test cases by:
807815
For more information and a high level example, see:
808816
./swift/utils/bug_reducer/README.md.
809817

818+
# Debugging the Compiler Build
819+
820+
## Build Dry Run
821+
822+
A "dry-run" invocation of the `build-script` (using the `--dry-run` flag) will
823+
print the commands that would be executed in a given build, without executing
824+
them. A dry-run script invocation output can be used to inspect the build stages
825+
of a given `build-script` configuration, or create script corresponding to one
826+
such configuration.
827+
828+
# Debugging the Compiler Driver
829+
830+
The Swift compiler uses a standalone compiler-driver application written in
831+
Swift: [swift-driver](https://github.com/apple/swift-driver). When building the
832+
compiler using `build-script`, by default, the standalone driver will be built
833+
first, using the host toolchain, if the host toolchain contains a Swift
834+
compiler. If the host toolchain does not contain Swift, a warning is emitted and
835+
the legacy compiler-driver (integrated in the C++ code-base) will be used. In
836+
the future, a host toolchain containing a Swift compiler may become mandatory.
837+
Once the compiler is built, the compiler build directory (`swift-<OS>-<ARCH>`)
838+
is updated with a symlink to the standalone driver, ensuring calls to the build
839+
directory's `swift` and `swiftc` always forward to the standalone driver.
840+
841+
For more information about the driver, see:
842+
[github.com/apple/swift-driver/blob/main/README.md](https://github.com/apple/swift-driver/blob/main/README.md)
843+
844+
## Swift Compiler Driver F.A.Q.
845+
> What's the difference between invoking 'swiftc' vs. 'swift-driver' at the top
846+
level?
847+
848+
Today, `swift` and `swiftc` are symbolic links to the compiler binary
849+
(`swift-frontend`). Invoking `swiftc` causes the executable to detects that it
850+
is a compiler-driver invocation, and not a direct compiler-frontend invocation,
851+
by examining the invoked program's name. The compiler frontend can be invoked
852+
directly by invoking the `swift-frontend` executable, or passing in the
853+
`-frontend` option to `swiftc`.
854+
855+
The standalone [Compiler Driver](https://github.com/apple/swift-driver) is
856+
installed as a separate `swift-driver` executable in the Swift toolchain's `bin`
857+
directory. When a user launches the compiler by invoking `swiftc`, the C++ based
858+
compiler executable forwards the invocation to the `swift-driver` executable if
859+
one is found alongside it. This forwarding mechanism is in-place temporarily, to
860+
allow for an easy fallback to the legacy driver via one of the two escape
861+
hatches:
862+
863+
- `-disallow-use-new-driver` command line flag
864+
- `SWIFT_USE_OLD_DRIVER` environment variable
865+
866+
If the user is to directly invoke the `swift-driver` executable, the behaviour
867+
should be the same as invoking the `swiftc` executable, but without the option
868+
for a legacy driver fallback.
869+
870+
Once the legacy driver is deprecated, `swift` and `swiftc` executables will
871+
become symbolic links to the `swift-driver` executable directly.
872+
873+
874+
> Will 'swiftc ... -###' always print the same set of commands for the old/new
875+
driver? Do they call 'swift-frontend' the same way?
876+
877+
The standalone [Compiler Driver](https://github.com/apple/swift-driver) is meant
878+
to be a direct drop-in replacement for the C++-based legacy driver. It has the
879+
exact same command-line interface. The expectation is that its behaviour closely
880+
matches the legacy driver; however, during, and after the transition to the new
881+
driver being the default its behaviour may start to diverge from the legacy
882+
driver as par for the course of its evolution and gaining new features, etc.
883+
Today, broadly-speaking, sets of `swift-frontend` invocations generated by the
884+
two drivers are expected to be very similar.
885+
886+
## Building the compiler without the standalone driver
887+
One can build the compiler that does not rely on the standalone driver and
888+
instead uses the legacy, built-in driver using the `build-script` option:
889+
`--skip-early-swift-driver`.
890+
891+
## Invoking the compiler without forwarding to the standalone driver
892+
The Swift compiler can currently be invoked in an execution mode that will use
893+
the legacy C++-based compiler driver using one of the following two options:
894+
- Passing `-disallow-use-new-driver` argument to the `swiftc` invocation
895+
- Setting the `SWIFT_USE_OLD_DRIVER` environment variable
896+
897+
## Reproducing the Compiler Driver build steps
898+
A "[dry-run](#build-dry-run)" invocation of the `build-script` can be used to
899+
examine the SwiftDriver build stage and commands, without executing it. For
900+
example:
901+
```
902+
$ utils/build-script --release-debuginfo --dry-run
903+
+ mkdir -p /SwiftWorkspace/build/Ninja-RelWithDebInfoAssert
904+
--- Building earlyswiftdriver ---
905+
+ /SwiftWorkspace/swift-driver/Utilities/build-script-helper.py build --package-path /SwiftWorkspace/swift-driver --build-path /SwiftWorkspace/build/Ninja-RelWithDebInfoAssert/earlyswiftdriver-macosx-x86_64 --configuration release --toolchain /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr --ninja-bin /Applications/Xcode.app/Contents/Developer/usr/local/bin/ninja --cmake-bin /Applications/Xcode.app/Contents/Developer/usr/local/bin/cmake --local_compiler_build
906+
Building the standard library for: swift-test-stdlib-macosx-x86_64
907+
...
908+
```
909+
One of the first steps is an invocation of the driver's
910+
`build-script-helper.py` script which specifies that the driver us to be built
911+
(`build`) using the host toolchain (`--toolchain`) to a specified location
912+
(`--build-path`).
913+
914+
## Installing the Compiler Driver
915+
In order to create a Swift compiler installation (`--install-swift`), the
916+
standalone driver must be built as a separate build product using the
917+
*just-built* Swift compiler and toolchain (the ones built in the same
918+
`build-script` invocation, preceeding the SwiftDriver build product). The
919+
additional build product is added to the build by specifying the
920+
`--swift-driver` option of the `build-script`. The driver product is istalled
921+
into the resulting toolchain installation by specifying the
922+
`--install-swift-driver` option of the `build-script`.
923+
924+
Note, a "dry-run" `build-script` invocation when installing the standalone
925+
driver will demonstrate the commands required to build and install the driver as
926+
a standalone build product:
927+
```
928+
$ utils/build-script --release-debuginfo --dry-run --swift-driver --install-swift-driver
929+
...
930+
--- Cleaning swiftdriver ---
931+
+ /SwiftWorkspace/swift-driver/Utilities/build-script-helper.py clean --package-path /SwiftWorkspace/swift-driver --build-path /SwiftWorkspace/build/Ninja-RelWithDebInfoAssert/swiftdriver-macosx-x86_64 --configuration release --toolchain /SwiftWorkspace/build/Ninja-RelWithDebInfoAssert/toolchain-macosx-x86_64/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr --ninja-bin /Applications/Xcode.app/Contents/Developer/usr/local/bin/ninja --cmake-bin /Applications/Xcode.app/Contents/Developer/usr/local/bin/cmake
932+
--- Building swiftdriver ---
933+
+ /SwiftWorkspace/swift-driver/Utilities/build-script-helper.py build --package-path /SwiftWorkspace/swift-driver --build-path /SwiftWorkspace/build/Ninja-RelWithDebInfoAssert/swiftdriver-macosx-x86_64 --configuration release --toolchain /SwiftWorkspace/build/Ninja-RelWithDebInfoAssert/toolchain-macosx-x86_64/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr --ninja-bin /Applications/Xcode.app/Contents/Developer/usr/local/bin/ninja --cmake-bin /Applications/Xcode.app/Contents/Developer/usr/local/bin/cmake
934+
--- Installing swiftdriver ---
935+
+ /SwiftWorkspace/swift-driver/Utilities/build-script-helper.py install --package-path /SwiftWorkspace/swift-driver --build-path /SwiftWorkspace/build/Ninja-RelWithDebInfoAssert/swiftdriver-macosx-x
936+
86_64 --configuration release --toolchain /SwiftWorkspace/build/Ninja-RelWithDebInfoAssert/toolchain-macosx-x86_64/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr --ninja-bin /Applications/Xcode.app/Contents/Developer/usr/local/bin/ninja --cmake-bin /Applications/Xcode.app/Contents/Developer/usr/local/bin/cmake
937+
```
938+
These invocations of the driver's `build-script-helper.py` script specify the
939+
individual build actions (`clean`, `build`, `install`), the product build path
940+
(`--build-path`), and the *just-built* toolchain which should be used
941+
(`--toolchain`).
942+
810943
# Debugging Swift Executables
811944

812945
One can use the previous tips for debugging the Swift compiler with Swift

0 commit comments

Comments
 (0)