llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.69k stars 11.87k forks source link

No other way than -fuse-ld=lld can enable ld64.lld #52685

Open glandium opened 2 years ago

glandium commented 2 years ago

I was looking at applying a local patch to default clang to using ld64.lld for darwin targets. The naive approach of adding a getDefaultLinker implementation that returns ld64.lld in Darwin.h doesn't work, because of the LinkerIsLLD business in ToolChain::GetLinkerPath that only actually works for fuse-ld=lld. So, e.g. --ld-path=/path/to/ld64.lld doesn't work either.

Cc: @nico @int3 @keith

MaskRay commented 2 years ago

--ld-path=path is the recommended way to specify the linker path. -fuse-ld= is expected to take just a word but is often misused to accept an absolute/relative path. It is possible that at some point -fuse-ld=word may be used to control code generation behavior (for LTO options and specific optimizations this demand might be higher in the future).

keith commented 2 years ago

Even though we should recommend --ld-path in general, if -fuse-ld=lld is going to continue to work for other platforms we should probably try and make it work for darwin as well now?

glandium commented 2 years ago

I might not have been clear enough. -fuse-ld=lld is the only thing that works to enable ld64.lld for darwin. Everything else fails because the code in clang/lib/Driver/ToolChains/Darwin.cpp doesn't know the linker is lld and doesn't use the right flags. lld then says things like:

ld64.lld: error: must specify -platform_version
ld64.lld: error: foo.o has platform macOS, which is different from target platform unknown
ld64.lld: error: (...)/usr/lib/libSystem.tbd(/usr/lib/libSystem.B.dylib) is incompatible with x86_64 (unknown)
MaskRay commented 2 years ago

-fuse-ld=word will be kept. -fuse-ld=relative/path and -fuse-ld=/absolute/path are deprecated. There is a Bazel bug about migrating away from -fuse-ld=/absolute/path: https://github.com/bazelbuild/bazel/issues/13252

If one wants to use ld64.lld with a different path, -fuse-ld=lld --ld-path=/path/to/ld64.lld or -B path -fuse-ld=lld. The -B semantics are somewhat complex (https://maskray.me/blog/2021-03-28-compiler-driver-and-cross-compilation#search-paths) and affect other search paths, so I do not recommend it.

I think CMake -DCLANG_DEFAULT_LINKER=lld just works. If it doesn't, you can fix it:)

llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-driver