Skip to content

Commit 6f44ba4

Browse files
authored
Merge pull request #37122 from artemcm/BringBackNewDriver
Revert "Merge pull request #37114 from apple/revert-36377-NewDriverDefault"
2 parents 4b068ac + ae2e856 commit 6f44ba4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+580
-41
lines changed

cmake/modules/SwiftUtils.cmake

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,35 @@ function(swift_create_post_build_symlink target)
152152
COMMENT "${CS_COMMENT}")
153153
endfunction()
154154

155+
# Once swift-frontend is built, if the standalone (early) swift-driver has been built,
156+
# we create a `swift-driver` symlink adjacent to the `swift` and `swiftc` executables
157+
# to ensure that `swiftc` forwards to the standalone driver when invoked.
158+
function(swift_create_early_driver_symlinks target)
159+
# Early swift-driver is built adjacent to the compiler (swift build dir)
160+
set(driver_bin_dir "${CMAKE_BINARY_DIR}/../earlyswiftdriver-${SWIFT_HOST_VARIANT}-${SWIFT_HOST_VARIANT_ARCH}/release/bin")
161+
set(swift_bin_dir "${SWIFT_RUNTIME_OUTPUT_INTDIR}")
162+
# If early swift-driver wasn't built, nothing to do here.
163+
if(NOT EXISTS "${driver_bin_dir}/swift-driver" OR NOT EXISTS "${driver_bin_dir}/swift-help")
164+
message(STATUS "Skipping creating early SwiftDriver symlinks - no early SwiftDriver build found.")
165+
return()
166+
endif()
167+
168+
message(STATUS "Creating early SwiftDriver symlinks.")
169+
message(STATUS "From: ${driver_bin_dir}/swift-driver")
170+
message(STATUS "To: ${swift_bin_dir}/swift-driver")
171+
swift_create_post_build_symlink(swift-frontend
172+
SOURCE "${driver_bin_dir}/swift-driver"
173+
DESTINATION "${swift_bin_dir}/swift-driver"
174+
COMMENT "Creating early SwiftDriver symlinks: swift-driver")
175+
176+
message(STATUS "From: ${driver_bin_dir}/swift-help")
177+
message(STATUS "To: ${swift_bin_dir}/swift-help")
178+
swift_create_post_build_symlink(swift-frontend
179+
SOURCE "${driver_bin_dir}/swift-help"
180+
DESTINATION "${swift_bin_dir}/swift-help"
181+
COMMENT "Creating early SwiftDriver symlinks: swift-help")
182+
endfunction()
183+
155184
function(dump_swift_vars)
156185
set(SWIFT_STDLIB_GLOBAL_CMAKE_CACHE)
157186
get_cmake_property(variableNames VARIABLES)

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

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ set(TEST_SUBSETS
188188
only_validation
189189
only_long
190190
only_stress
191+
only_early_swiftdriver
191192
)
192193

193194
if(NOT "${COVERAGE_DB}" STREQUAL "")
@@ -353,6 +354,7 @@ foreach(SDK ${SWIFT_SDKS})
353354
(test_subset STREQUAL "validation") OR
354355
(test_subset STREQUAL "only_long") OR
355356
(test_subset STREQUAL "only_stress") OR
357+
(test_subset STREQUAL "only_early_swiftdriver") OR
356358
(test_subset STREQUAL "all"))
357359
list(APPEND directories "${test_bin_dir}")
358360
endif()

test/Unit/lit.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ elif swift_test_subset == 'only_stress':
6363
# Currently those tests are very fast so it doesn't matter much.
6464
pass
6565
else:
66-
lit_config.fatal("Unknown test mode %r" % swift_test_subset)
66+
lit_config.fatal("Unknown test subset %r" % swift_test_subset)
6767

6868
# test_source_root: The root path where tests are located.
6969
# test_exec_root: The root path where tests should be run.

test/lit.cfg

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,10 @@ elif swift_test_subset == 'only_stress':
647647
config.available_features.add("stress_test")
648648
config.limit_to_features.add("stress_test")
649649
config.limit_to_features.discard("executable_test")
650+
elif swift_test_subset == 'only_early_swiftdriver':
651+
# Point this subset at a driver-specific set of tests. These are the known reduced subset
652+
# of tests to verify the basic functionality of the standalone (early) swift-driver.
653+
config.test_source_root = os.path.join(config.test_source_root, 'Driver', 'Dependencies')
650654
else:
651655
lit_config.fatal("Unknown test mode %r" % swift_test_subset)
652656

@@ -656,6 +660,13 @@ if 'swift_evolve' in lit_config.params:
656660
if not 'swift_driver' in lit_config.params:
657661
config.available_features.add("cplusplus_driver")
658662

663+
# Check if we need to run lit tests using the legacy driver or the new driver
664+
# The default for existing test runs is to use the legacy driver.
665+
# The new driver is tested separately.
666+
if swift_test_subset != 'only_early_swiftdriver' and\
667+
os.environ.get('SWIFT_FORCE_TEST_NEW_DRIVER') is None:
668+
config.environment['SWIFT_USE_OLD_DRIVER'] = '1'
669+
659670
# Enable benchmark testing when the binary is found (has fully qualified path).
660671
if config.benchmark_o != 'Benchmark_O':
661672
config.available_features.add('benchmark')

tools/driver/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ target_link_libraries(swift-frontend
1616
swiftSymbolGraphGen
1717
LLVMBitstreamReader)
1818

19+
# Create a `swift-driver` symlinks adjacent to the `swift-frontend` executable
20+
# to ensure that `swiftc` forwards to the standalone driver when invoked.
21+
swift_create_early_driver_symlinks(swift-frontend)
22+
1923
swift_create_post_build_symlink(swift-frontend
2024
SOURCE "swift-frontend${CMAKE_EXECUTABLE_SUFFIX}"
2125
DESTINATION "swift${CMAKE_EXECUTABLE_SUFFIX}"

0 commit comments

Comments
 (0)