I was trying to use -DLLVM_ENABLE_RUNTIMES=compiler-rt on FreeBSD and this
failed since the 32-bit build ended up linking against the 64-bit ASAN
runtime and linking with "/usr/local/bin/x86_64-unknown-freebsd12.2-ld".
Looking at the driver code shows that the triple used as a prefix for tools
and libaries is always the raw value passed to -target and is not affected
by flags such as -m32/-march/etc.
While the 64-bit linker can usually link 32-bit programs just fine, the real
problem here is that search paths for the compiler-rt builtins/sanitizer
runtimes use the raw target triple and we can therefore end up linking
against the 64-bit runtime instead of the 32-bit one. In my case the build
of compiler-rt failed because "--whole-archive" "....llvm-project-build/./lib/clang/13.0.0/lib/x86_64-unknown-freebsd12.2/libclang_rt.asan_cxx.a"
was being passed to the linker instead of using the 32-bit library that
can be found in ".../lib/clang/13.0.0/lib/i386-unknown-freebsd12.2/".
This commit uses computeTargetTriple() to update the triple used as a
prefix for tools such as the linker. If computeTargetTriple() results in
a different triple, we update the RawTargetTriple and now search for
i386-unknown-freebsd12.2-ld when -m32 is passed. It is important to note
that we do not normalize the triple passed to -target since adding
additional could result in an unexpected behaviour change. For example,
clang -target x86_64-freebsd13 should search for x86_64-freebsd13-ld
and not the normalized x86_64-unknown-freebsd13-ld and
clang -target x86_64-freebsd13 -m32 tries to find i386-unknown-freebsd13-ld.
I think this should be handled by each toolchain. For example Linux toolchain already has getMultiarchTriple which takes into account target handling on various existing platforms like Debian.
What I've been thinking of doing is to move that method to the ToolChain class as virtual so it could be overriden and customized by each toolchain, and then use it in getRuntimePath.