Building Swift compiler from source fails with R_AARCH64_PREL32 relocation errors on ARM64 Linux (OrbStack VM)

Summary

I'm trying to build the Swift compiler from source on ARM64 Linux (Ubuntu 22.04 running in OrbStack on Apple Silicon). The build fails when linking libSwiftSyntax.so and lib_CompilerSwiftSyntax.so with PIC-related relocation errors. I've tested with both Swift 6.0.3 and Swift 6.2.3 as the host toolchain, and both fail with the same error.

Environment

  • OS: Ubuntu 22.04.5 LTS (aarch64)
  • Kernel: 6.17.8-orbstack (OrbStack VM on Apple Silicon Mac)
  • Host Swift: 6.2.3 (installed via swiftly), also tested with 6.0.3
  • Linker: GNU ld 2.38
  • Swift source: release/6.2 branch (commit 554156bccc696a7d7cfc044c82a5914a9fc643c7)

Build Command

utils/build-script --release-debuginfo --sccache --bootstrapping=hosttools --reconfigure

Error

When linking SwiftSyntax shared libraries, the build fails with:

FAILED: lib/swift/host/compiler/lib_CompilerSwiftSyntax.so
/usr/bin/ld: _deps/compilerswiftsyntax-build/Sources/SwiftSyntax/CMakeFiles/_CompilerSwiftSyntax.dir/AbsolutePosition.swift.o:
relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `$s20_CompilerSwiftSyntax16AbsolutePositionVSLAAMc'
which may bind externally can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: _deps/compilerswiftsyntax-build/Sources/SwiftSyntax/CMakeFiles/_CompilerSwiftSyntax.dir/AbsolutePosition.swift.o:
relocation R_AARCH64_PREL32 against symbol `$s20_CompilerSwiftSyntax16AbsolutePositionVMn'
which may bind externally can not be used when making a shared object; recompile with -fPIC
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The error occurs for many symbols across multiple .swift.o files in SwiftSyntax. The linker is complaining that the object files were not compiled with position-independent code (PIC), which is required for shared libraries.

Similar issue: Building Swift on linux, fails at linking of libswiftCore.so

Compiler Invocation

The failing link command uses:

cd /home/kyle/swift-project/swift/SwiftCompilerSources && /home/kyle/.local/share/swiftly/bin/swiftc -target aarch64-unknown-linux-gnu -emit-library -o lib/swift/host/compiler/lib_CompilerSwiftSyntax.so \
-module-name SwiftSyntax -O -g -wmo ... \
-Xlinker -soname -Xlinker lib_CompilerSwiftSyntax.so \
[many .swift source files]

What I've Tried

  1. Clean build with --reconfigure flag
  2. Different Swift versions: Both 6.0.3 and 6.2.3 fail identically
  3. Removed build artifacts and rebuilt from scratch

Questions

  1. Is there a known issue with building Swift on ARM64 Linux where PIC code isn't being generated for shared libraries?

  2. Is there a build flag I should be passing to ensure PIC code generation?

  3. Could this be related to running in an OrbStack VM specifically, or is this a general ARM64 Linux issue?

  4. Are there any workarounds, such as building with static libraries instead?

Any guidance would be greatly appreciated!

There is an Ubuntu 22.04 AArch64 CI set up for that 6.2 branch, and as of its last runs last month, was working well. One big difference is that it still uses Swift 5.9.2 for its prebuilt host compiler, so its possible that older 6.2 branch cannot be built with the newer Swift 6 prebuilt host compilers you are using instead.

1 Like

I’m not sure if it’s the same issue, but I’ve seen some problems arise from the choice of linker. Making sure the compilation uses lld fixed the issues for me.

If it helps, here is a devcontainer configuration I used for development: GitHub - GeorgeLyon/swift-devcontainer: Devcontainer configuration for developing Swift.

This is what I think fixed the issue for me:

2 Likes

I tried 5.9.2. But it will report many missing binary here when building.

/usr/bin/env: ‘llvm-ranlib’: No such file or directory 
/usr/bin/env: ‘llvm-objcopy’: No such file or directory

For the first one, we can workaround by ~/.local/share/swiftly/toolchains/5.9.2/usr/bin$ ln -s llvm-ar ~/.local/share/swiftly/toolchains/5.9.2/usr/bin/llvm-ranlib

For the second one, we can workaround by ln -s ~/.local/share/swiftly/toolchains/6.2.3/usr/bin/llvm-objcopy ~/.local/share/swiftly/toolchains/5.9.2/usr/bin/llvm-objcopy assuming they are compatibable.

But then it will come with another issue:

~/swift-project/swift
+ /home/kyle/swift-project/build/cmake-linux-aarch64/bin/cmake --build /home/kyle/swift-project/build/Ninja-RelWithDebInfoAssert/swift-linux-aarch64 -- -j14 all swift-test-stdlib-linux-aarch64 swift-libexec-linux-aarch64
ninja: error: '/home/kyle/.local/share/swiftly/lib/swift/linux/aarch64/swiftrt.o', needed by 'lib/libswiftDemangle.so', missing and no known rule to make it
Building the standard library for: swift-test-stdlib-linux-aarch64

I was stuck at that time. So I then tried the lld method.

/usr/bin/ld.lld does not exist on my env. But it should exit on the llvm/clang product.

So I just use -DLLVM_USE_LINKER=lld to achieve the same effect.

The full command is

# with 6.2.3 as hosttools
utils/build-script --release-debuginfo --sccache --bootstrapping=hosttools --reconfigure \
  --extra-cmake-options="-DLLVM_USE_LINKER=lld" &> ../build/log.txt

But then it will hit the same issue:

+ /home/kyle/swift-project/build/cmake-linux-aarch64/bin/cmake --build /home/kyle/swift-project/build/Ninja-RelWithDebInfoAssert/swift-linux-aarch64 -- -j14 all swift-test-stdlib-linux-aarch64 swift-libexec-linux-aarch64
ninja: error: '/home/kyle/.local/share/swiftly/lib/swift/linux/aarch64/swiftrt.o', needed by 'lib/libswiftDemangle.so', missing and no known rule to make it
Building the standard library for: swift-test-stdlib-linux-aarch64

It looks to be a swiftly issue. (Reported here Toolchain installed by swiftly has trouble as a hosttools when compiling compiler · Issue #489 · swiftlang/swiftly · GitHub)

So I just unlink swiftly and manage the path myself then.

Build Script Log: /home/kyle/swift-project/build/.build_script_log
Build Percentage 	 Build Duration (sec) 	 Build Phase
================ 	 ==================== 	 ===========
54.1%             	 1205.34               	 Building llvm
43.6%             	 971.41                	 linux-aarch64-swift-build
2.1%              	 47.47                 	 Building earlyswiftdriver
0.1%              	 1.61                  	 Building cmark
0.0%              	 0.02                  	 linux-aarch64-swift-test
0.0%              	 0.02                  	 linux-aarch64-swift-install
0.0%              	 0.02                  	 linux-aarch64-extractsymbols
0.0%              	 0.02                  	 merged-hosts-lipo
0.0%              	 0.01                  	 merged-hosts-lipo-core
0.0%              	 0.01                  	 linux-aarch64-package
Total Duration: 2225.93 seconds (37m 5s)
Building the standard library for: swift-test-stdlib-linux-aarch64
1 Like