In order to do this, I need to:
- Build the Swift project using
lld on Linux in such a way that,
- The built Swift defaults to also using
lld
1. Building with LLD:
I'm doing a 3-stage build and it seems to have worked out thus far. The first has bootstrapping and macros disabled since I don't have an initial Swift compiler.
There are a handful of variables, but it generally looks like this:
STAGE0_DIR=$BASE_INSTALL/swift-stage0-install
$SOURCES/swift/utils/build-script --release \
--build-subdir=amazonlinux2023/stage0 \
--install-destdir=$STAGE0_DIR \
--skip-build-benchmarks --skip-test-cmark \
--skip-early-swift-driver --skip-early-swiftsyntax \
--bootstrapping=off \
--llvm-targets-to-build=X86 \
--libdispatch --foundation --swiftpm --xctest --llbuild --swift-driver \
--extra-cmake-options='-DSWIFT_USE_LINKER=lld' \
--install-all
Then since I have a Swift compiler, I can build the Swift bits of the compiler, so that is stage 1:
STAGE1_DIR=$BASE_INSTALL/swift-stage1-install
PATH="$STAGE0_DIR/usr/bin:$PATH" \
$SOURCES/swift/utils/build-script --release \
--build-subdir=amazonlinux2023/stage1 \
--install-destdir=$STAGE1_DIR \
--skip-build-benchmarks --skip-test-cmark \
--bootstrapping=off \
--llvm-targets-to-build=X86 \
--libdispatch --foundation --swiftpm --xctest --llbuild --swift-driver \
--extra-cmake-options='-DSWIFT_USE_LINKER=lld' \
--verbose-build \
--install-all
And finally, we have a fully working Swift compiler with all the features, we can build the actual toolchain in the third stage:
STAGE2_DIR=$BASE_INSTALL/swift-stage2-install
PATH="$STAGE1_DIR/usr/bin:$PATH" \
$SOURCES/swift/utils/build-script \
--preset=buildbot_linux,lld,no_test \
build_subdir="amazonlinux2023/stage2" \
installable_package=$STAGE2_DIR/x86_64-swift-5.10-amazonlinux-2023-notest.tar.gz \
install_destdir=$STAGE2_DIR
I've got extra presets for pulling in lld in the full toolchain, so you'll need to add this to the utils/build-presets.ini file before running that stage2:
[preset: mixin_lld]
extra-cmake-options=
-DSWIFT_USE_LINKER=lld
llvm-cmake-options=
-DCLANG_DEFAULT_LINKER=lld
[preset: buildbot_linux,lld]
mixin-preset=
buildbot_linux
mixin_lld
[preset: buildbot_linux,lld,no_assertions]
mixin-preset=
buildbot_linux,no_assertions
mixin_lld
[preset: buildbot_linux,lld,no_test]
mixin-preset=
buildbot_linux,no_test
mixin_lld
[preset: buildbot_linux,lld,no_assertions,no_test]
mixin-preset=
buildbot_linux,no_assertions,no_test
mixin_lld
Then I do one more build, but sharing the build directory of the third-stage where I enable and run the tests.
PATH="$STAGE1_DIR/usr/bin:$PATH" \
$SOURCES/swift/utils/build-script \
--preset=buildbot_linux,lld \
build_subdir="amazonlinus2023/stage2" \
installable_package=$STAGE2_DIR/x86_64-swift-5.10-amazonlinux-2023.tar.gz \
install_destdir=$STAGE2_DIR 2>&1 | tee $SOURCES/build/amazonlinux2023/test.log
It'a definitely a process.
I don't know what the "assingment of LLVM_15 to symbol indexstore_blarpy failed: symbol not defined" is though.
I haven't run into that.
2. Changing the default linker of the produced toolchain
On 5.10, the default linker is hard-coded string in both drivers, so there's no knob to turn to change the default. To work around it, I'm currently just applying a patch that rips out all of the logic in defaultLinker and replaces it with this:
private func defaultLinker(for targetTriple: Triple) -> String? {
"lld"
}
This ensures that the driver still automatically adds -Xlinker -z -Xlinker nostart-stop-gc so that we keep the missing symbols.
On main, I've removed all of the cleverness so that the swift-driver just uses the clang-linker to decide. This means that setting CLANG_DEFAULT_LINKER=lld during the toolchain build will mean that the produced toolchain will use lld as the default linker, both for C/C++ and Swift.
Another piece of good news, BFD (the normal ld on Linux) was patched so that it can handle relocating the protected symbols (the issue preventing using it in the first place). At the very least, AmazonLinux2023 has a new enough ld that it works out-of-the-box. I don't know which version Gentoo has, but if it's recent, you may not even need lld and clang will "just work".