This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Ignore CLANG_DEFAULT_LINKER for custom-linker toolchains
AcceptedPublic

Authored by simoll on Dec 3 2021, 7:59 AM.

Details

Summary

Before, the CLANG_DEFAULT_LINKER cmake option was a global override for
the linker that shall be used on all toolchains. The linker binary
specified that way may not be available on toolchains with custom
linkers. Eg, the only linker for VE is named 'nld' - any other linker
invalidates the toolchain.

This patch removes the hard override and instead lets the generic
toolchain implementation default to CLANG_DEFAULT_LINKER. Toolchains
can now deviate with a custom linker name or deliberatly default to
CLANG_DEFAULT_LINKER.

Diff Detail

Event Timeline

simoll requested review of this revision.Dec 3 2021, 7:59 AM
simoll created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptDec 3 2021, 7:59 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
phosek accepted this revision.Dec 3 2021, 12:58 PM

LGTM

This revision is now accepted and ready to land.Dec 3 2021, 12:58 PM
MaskRay accepted this revision.Dec 3 2021, 4:17 PM

LGTM.

clang/lib/Driver/ToolChain.cpp
545

CLANG_DEFAUALT_LINKER[0] == '\0'

simoll updated this revision to Diff 391998.Dec 6 2021, 2:04 AM
simoll marked an inline comment as done.

Simplified empty-string check as suggested

ronlieb added a subscriber: ronlieb.Dec 6 2021, 7:10 AM

Hi Simon,
i am seeing a failure in our amdgpu buildbot after this patch . https://lab.llvm.org/staging/#/builders/200/builds/1407
we do depend on the cmake flag you removed.
we specify this
-DCLANG_DEFAULT_LINKER=lld

FAILED: openmp/libomptarget/libomptarget.rtl.x86_64.so
: && /home/rlieberm/mono-repo/llvm-project/build/./bin/clang++ --target=x86_64-unknown-linux-gnu -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wstring-conversion -Wmisleading-indentation -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -Wcast-qual -Wformat-pedantic -Wimplicit-fallthrough -Wsign-compare -Wno-extra -Wno-pedantic -std=c++14 -O3 -DNDEBUG -Wl,-z,defs -Wl,-z,nodelete -Wl,--color-diagnostics -shared -Wl,-soname,libomptarget.rtl.x86_64.so -o openmp/libomptarget/libomptarget.rtl.x86_64.so openmp/libomptarget/plugins/common/elf_common/CMakeFiles/elf_common.dir/elf_common.cpp.o openmp/libomptarget/plugins/x86_64/CMakeFiles/omptarget.rtl.x86_64.dir/__/generic-elf-64bit/src/rtl.cpp.o /usr/lib/x86_64-linux-gnu/libffi.so /usr/lib/x86_64-linux-gnu/libelf.so -ldl -lpthread -Wl,--version-script=/home/rlieberm/mono-repo/llvm-project/openmp/libomptarget/plugins/x86_64/../exports /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMObject.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMBitReader.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMCore.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMRemarks.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMBitstreamReader.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMMCParser.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMMC.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMDebugInfoCodeView.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMTextAPI.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMBinaryFormat.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMSupport.a -lrt -lm /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/x86_64-linux-gnu/libtinfo.so /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMDemangle.a -ldl -lpthread && :
lld is a generic driver.
Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld (WebAssembly) instead
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)

simoll reopened this revision.Dec 6 2021, 7:47 AM

I've reverted the patch for now, this may show up for other toolchains, too.

This patch has pushed down the responsibility for handling -DCLANG_DEFAULT_LINKER to the toolchains.
However, I did not modify all toolchains to account for that. Pending an update..

Hi Simon,
i am seeing a failure in our amdgpu buildbot after this patch . https://lab.llvm.org/staging/#/builders/200/builds/1407
we do depend on the cmake flag you removed.
we specify this
-DCLANG_DEFAULT_LINKER=lld

FAILED: openmp/libomptarget/libomptarget.rtl.x86_64.so
: && /home/rlieberm/mono-repo/llvm-project/build/./bin/clang++ --target=x86_64-unknown-linux-gnu -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wstring-conversion -Wmisleading-indentation -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -Wcast-qual -Wformat-pedantic -Wimplicit-fallthrough -Wsign-compare -Wno-extra -Wno-pedantic -std=c++14 -O3 -DNDEBUG -Wl,-z,defs -Wl,-z,nodelete -Wl,--color-diagnostics -shared -Wl,-soname,libomptarget.rtl.x86_64.so -o openmp/libomptarget/libomptarget.rtl.x86_64.so openmp/libomptarget/plugins/common/elf_common/CMakeFiles/elf_common.dir/elf_common.cpp.o openmp/libomptarget/plugins/x86_64/CMakeFiles/omptarget.rtl.x86_64.dir/__/generic-elf-64bit/src/rtl.cpp.o /usr/lib/x86_64-linux-gnu/libffi.so /usr/lib/x86_64-linux-gnu/libelf.so -ldl -lpthread -Wl,--version-script=/home/rlieberm/mono-repo/llvm-project/openmp/libomptarget/plugins/x86_64/../exports /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMObject.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMBitReader.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMCore.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMRemarks.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMBitstreamReader.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMMCParser.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMMC.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMDebugInfoCodeView.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMTextAPI.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMBinaryFormat.a /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMSupport.a -lrt -lm /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/x86_64-linux-gnu/libtinfo.so /home/rlieberm/mono-repo/llvm-project/build/lib/libLLVMDemangle.a -ldl -lpthread && :
lld is a generic driver.
Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld (WebAssembly) instead
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)

This revision is now accepted and ready to land.Dec 6 2021, 7:47 AM

fyi: if i remove the now 'dead' use of the CMAKE variable from my cmake , then i am able to build. so i see you reverted, thx. i guess some coordination amongst buildbot maintainers who might use this option

checking zorg: the last two are me: not sure who owns the 1st one
"clang-ppc64le-rhel"
"openmp-offload-amdgpu-runtime"
"openmp-offload-amdgpu-runtime-experimental"

simoll updated this revision to Diff 392067.Dec 6 2021, 8:00 AM

Use the -DCLANG_DEFAULT_LINKER linker in all toolchains but VE. Since toolchains are now responsible for this flag, there is a new helper function that emulates the old linker selection behavior.
This should unbreak the AMDGPU staging bot.

simoll updated this revision to Diff 392297.Dec 7 2021, 12:30 AM

Formatting / Cleanup

phosek added a comment.Dec 7 2021, 1:00 AM

I don't think the updated logic is correct. For example, in the case of Fuchsia we don't want to take CLANG_DEFAULT_LINKER into account, that's why we override getDefaultLinker. I assume it's the same for other toolchains that override getDefaultLinker.

The issue that affected AMDGPU bots is that StringRef UseLinker = A ? A->getValue() : "" is now going to evaluate to an empty string unless -fuse-ld= is set, and we'll take the UseLinker.empty() || UseLinker == "ld" branch, where const char *DefaultLinker = getDefaultLinker() is going to return "lld" because AMDGPU bot sets -DCLANG_DEFAULT_LINKER=lld in their build. That's not a valid name, the valid name is ld.lld. Prior to your patch, we would take the !llvm::sys::path::is_absolute(UseLinker) branch and construct the correct linker name by appending CLANG_DEFAULT_LINKER to '"ld."`.

I'd argue that your originally patch is actually the behavior we want. Rather, we shouldn't consider -DCLANG_DEFAULT_LINKER=lld as a valid value. Instead AMDGPU bot should use -DCLANG_DEFAULT_LINKER=ld.lld. Even better would be to introduce a second CMake variable so we can control the default value for -fuse-ld= and for --ld-path options separately. Right now it's not clear which of the two is controlled by -DCLANG_DEFAULT_LINKER= (that's because -DCLANG_DEFAULT_LINKER= actually predates the --ld-path option).

phosek added a comment.Dec 7 2021, 1:07 AM

I don't think the updated logic is correct. For example, in the case of Fuchsia we don't want to take CLANG_DEFAULT_LINKER into account, that's why we override getDefaultLinker. I assume it's the same for other toolchains that override getDefaultLinker.

The issue that affected AMDGPU bots is that StringRef UseLinker = A ? A->getValue() : "" is now going to evaluate to an empty string unless -fuse-ld= is set, and we'll take the UseLinker.empty() || UseLinker == "ld" branch, where const char *DefaultLinker = getDefaultLinker() is going to return "lld" because AMDGPU bot sets -DCLANG_DEFAULT_LINKER=lld in their build. That's not a valid name, the valid name is ld.lld. Prior to your patch, we would take the !llvm::sys::path::is_absolute(UseLinker) branch and construct the correct linker name by appending CLANG_DEFAULT_LINKER to '"ld."`.

I'd argue that your originally patch is actually the behavior we want. Rather, we shouldn't consider -DCLANG_DEFAULT_LINKER=lld as a valid value. Instead AMDGPU bot should use -DCLANG_DEFAULT_LINKER=ld.lld. Even better would be to introduce a second CMake variable so we can control the default value for -fuse-ld= and for --ld-path options separately. Right now it's not clear which of the two is controlled by -DCLANG_DEFAULT_LINKER= (that's because -DCLANG_DEFAULT_LINKER= actually predates the --ld-path option).

I forgot to mention, I don't think your updated logic is actually going to address the failure we've seen on the AMDGPU bot because the test failure they're seeing is not in the AMDGPU target, it's in the x86_64-unknown-linux-gnu target and that's still going to follow the control flow I described above.

Rather, we shouldn't consider -DCLANG_DEFAULT_LINKER=lld as a valid value. Instead AMDGPU bot should use -DCLANG_DEFAULT_LINKER=ld.lld.

I think this would be a kinda disruptive change; I (and others) specify it as -DCLANG_DEFAULT_LINKER=lld so far: https://github.com/mstorsjo/llvm-mingw/blob/master/build-llvm.sh#L162 And other projects too: https://github.com/msys2/MINGW-packages/blob/master/mingw-w64-clang/PKGBUILD#L204

phosek added a comment.Dec 7 2021, 1:51 AM

Rather, we shouldn't consider -DCLANG_DEFAULT_LINKER=lld as a valid value. Instead AMDGPU bot should use -DCLANG_DEFAULT_LINKER=ld.lld.

I think this would be a kinda disruptive change; I (and others) specify it as -DCLANG_DEFAULT_LINKER=lld so far: https://github.com/mstorsjo/llvm-mingw/blob/master/build-llvm.sh#L162 And other projects too: https://github.com/msys2/MINGW-packages/blob/master/mingw-w64-clang/PKGBUILD#L204

In that case, perhaps we should consider -DCLANG_DEFAULT_LINKER= to set the default value for -fuse-ld only and have another variable for --ld-path? Open question is if getDefaultLinker() should return the name of the linker or the filename. I'd argue for the former which would be consistent with -DCLANG_DEFAULT_LINKER=.

simoll added a comment.Dec 7 2021, 3:09 AM

I don't think the updated logic is correct. For example, in the case of Fuchsia we don't want to take CLANG_DEFAULT_LINKER into account, that's why we override getDefaultLinker. I assume it's the same for other toolchains that override getDefaultLinker.

You do. With the logic as before this patch, if CLANG_DEFAULT_LINKER is an absolute path, your build overrides the default linker on Fuchsia (and elsewhere).

The issue that affected AMDGPU bots is that StringRef UseLinker = A ? A->getValue() : "" is now going to evaluate to an empty string unless -fuse-ld= is set, and we'll take the UseLinker.empty() || UseLinker == "ld" branch, where const char *DefaultLinker = getDefaultLinker() is going to return "lld" because AMDGPU bot sets -DCLANG_DEFAULT_LINKER=lld in their build. That's not a valid name, the valid name is ld.lld. Prior to your patch, we would take the !llvm::sys::path::is_absolute(UseLinker) branch and construct the correct linker name by appending CLANG_DEFAULT_LINKER to '"ld."`.

Right, the updated patch does not emulate the old behavior here. What makes a linker name valid?

I'd argue that your originally patch is actually the behavior we want. Rather, we shouldn't consider -DCLANG_DEFAULT_LINKER=lld as a valid value. Instead AMDGPU bot should use -DCLANG_DEFAULT_LINKER=ld.lld. Even better would be to introduce a second CMake variable so we can control the default value for -fuse-ld= and for --ld-path options separately. Right now it's not clear which of the two is controlled by -DCLANG_DEFAULT_LINKER= (that's because -DCLANG_DEFAULT_LINKER= actually predates the --ld-path option).

The interplay of CLANG_DEFAULT_LINKER , -fuse-ld and --ld-path is really a mess. How do we proceed here?
To be honest, it is hard to change anything about these flags as any semantic change may result in breakage on some (maybe downstream) toolchain and build configuration.