Linking without gcc on GNU/Linux

Is there a way to tell Clang to invoke the link editor directly, not going through gcc?

With clang-15.0.0-6.fc38.x86_64, Clang does not pass the --sysroot option to the gcc linker command line, and it drops the -target argument as well (GCC would use -B instead, although it probably differs too significantly to be useful). It seems the easiest way to fix this is to use a Clang-only link, but that would mean that Clang needs built-in knowledge of all startup files and the dynamic linker path.

-fuse-ld=lld tells Clang to directly invoke lld, the LLVM linker.

That doesn’t happen with clang-15.0.0-6.fc38.x86_64. It still calls /usr/bin/gcc -fuse-ld=lld. It calls lld eventually, but it still does not handle the --sysroot/-target settings correctly.

Is this a Fedora-specific change? I don’t see a patch in the Fedora package sources that would cause this.

I think it depends on what target clang is using. A Linux target like x86_64-linux-gnu will invoke the linker directly. For example -v
"/usr/bin/ld" -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello.exe /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/11/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/lib -L/usr/lib /tmp/hello-51b257.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/11/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o

However if the target given to clang doesn’t have a specific driver it can fall back to the Generic_GCC driver (see Driver::getToolChain llvm-project/Driver.cpp at main · llvm/llvm-project · GitHub) which I think invokes GCC for the linker driver.

Is it possible that the target is going to Generic_GCC rather than the Linux driver?

Oh. I didn’t know about the Generic_GCC driver. Changing the -target argument to something that Clang recognizes avoids the /usr/bin/gcc detour. Thanks!

Can you file a bug for this in Fedora?

I don’t think there’s a Clang bug here. Maybe it could warn about partially recognized target specifiers (-target aarch64-linux-gnu instead of -target aarch64-lignux), but that wouldn’t be Fedora-specific, I think.

@fweimer-rh I think it might be a Fedora bug, because we hard-code a specific triple for clang, so if the clang driver can’t recognize that triple, that’s a bug I think.

Fair enough: clang: Generic_GCC driver selected with -target aarch64

@tstellar : it’s not Fedora specific, I have the same issue with main version of llvm. And it’s consistent throughout the toolchain. When using -target x86_64 and asking for bitcode generation, the target encoded in the bitcode remains x86_64 and doesn’t expand to the native platform, even though it’s a prefix of the asked target. That behavior a) makes sense to me b) is not specific to Fedora.

In the case of @fweimer-rh he wants to use a given linker and thus need to give accurate target information, that somehow makes sense. Considering warnings, +1 for a warning on unmatched triple components.

What I find confusing is that the prefix is recognized (it switches code generation), but it doesn’t switch linkers.

-target x86_64 is defined by LLVM’s triple rules as implicitly x86_64-unknown-elf

exploratory patch in ⚙ D139188 [Draft] Sanitize clang target triple, I’d appreciate thoughts. My basic problem is the normalization of triples :slight_smile: