Skip to content

[clang][Driver] Obey -fuse-ld=... for -print-prog-name=ld output #66698

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

frobtech
Copy link
Contributor

GCC makes -print-prog-name=ld a special case that looks up the
linker that will be used according to the -fuse-ld=... option
state. This makes Clang follow suit.

GCC makes `-print-prog-name=ld` a special case that looks up the
linker that will be used according to the `-fuse-ld=...` option
state.  This makes Clang follow suit.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Sep 18, 2023
@frobtech frobtech requested a review from petrhosek September 18, 2023 21:10
@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2023

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Changes

GCC makes -print-prog-name=ld a special case that looks up the
linker that will be used according to the -fuse-ld=... option
state. This makes Clang follow suit.


Full diff: https://github.com/llvm/llvm-project/pull/66698.diff

2 Files Affected:

  • (modified) clang/lib/Driver/Driver.cpp (+2-1)
  • (added) clang/test/Driver/print-prog-name-ld.c (+4)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 84b8fc7685fed42..afda1bb14b420b6 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2189,7 +2189,8 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
 
     // Null program name cannot have a path.
     if (! ProgName.empty())
-      llvm::outs() << GetProgramPath(ProgName, TC);
+      llvm::outs() << (ProgName == "ld" ? TC.GetLinkerPath()
+                                        : GetProgramPath(ProgName, TC));
 
     llvm::outs() << "\n";
     return false;
diff --git a/clang/test/Driver/print-prog-name-ld.c b/clang/test/Driver/print-prog-name-ld.c
new file mode 100644
index 000000000000000..0aa75306bb01a8d
--- /dev/null
+++ b/clang/test/Driver/print-prog-name-ld.c
@@ -0,0 +1,4 @@
+// Test that -print-prog-name=ld correctly obeys -fuse-ld=...
+
+// RUN: %clang -print-prog-name=ld -fuse-ld=lld 2>&1 | FileCheck %s
+// CHECK:{{.*ld(64)?\.lld}}

@frobtech frobtech marked this pull request as ready for review September 18, 2023 21:27
@MaskRay
Copy link
Member

MaskRay commented Sep 18, 2023

I think the 2013 GCC feature adding -fuse-ld= made this change, which is, frankly, strange. I wish that we don't this...
If you want to obtain the ld.lld path, try --print-prog-name=ld.lld?

lld has several names. For windows-msvc target triples it is lld-link, and for wasm triples it is wasm-ld.

@frobtech
Copy link
Contributor Author

I think the 2013 GCC feature adding -fuse-ld= made this change, which is, frankly, strange. I wish that we don't this...

It's too late now. Build system code in the wild uses $CC -print-prog-name=ld and then expects to be able to invoke that program to get the linker that $CC usually uses. When CC=gcc -fuse-ld=foo that works, but when CC=clang it doesn't, whether there's a -fuse-ld=... in there or just the default in the toolchain configuration is something other than ld, such as when ld.lld is the default.

lld has several names. For windows-msvc target triples it is lld-link, and for wasm triples it is wasm-ld.

ISTM that GetLinkerPath ought to produce the right name regardless and if it doesn't we can fix it to do so.

@MaskRay
Copy link
Member

MaskRay commented Sep 18, 2023

I think the 2013 GCC feature adding -fuse-ld= made this change, which is, frankly, strange. I wish that we don't this...

It's too late now. Build system code in the wild uses $CC -print-prog-name=ld and then expects to be able to invoke that program to get the linker that $CC usually uses. When CC=gcc -fuse-ld=foo that works, but when CC=clang it doesn't, whether there's a -fuse-ld=... in there or just the default in the toolchain configuration is something other than ld, such as when ld.lld is the default.

Can you comment on what projects need this? Can't we fix the projects instead? And what do they do with the linker path? Why don't they invoke the clang driver to run a link action?

There are quite a few distributions using lld by default and I haven't heard about any issue about -print-prog-name=ld.

lld has several names. For windows-msvc target triples it is lld-link, and for wasm triples it is wasm-ld.

ISTM that GetLinkerPath ought to produce the right name regardless and if it doesn't we can fix it to do so.

It is, but the current test will fail.

@frobtech
Copy link
Contributor Author

Can you comment on what projects need this? Can't we fix the projects instead? And what do they do with the linker path? Why don't they invoke the clang driver to run a link action?

They are legion. It comes from autoconf checks for libtool. It doesn't really matter why they're doing it. They are doing it and it will be years before they can all be changed. If you want to use Clang as the compiler for random open source code, it needs to be compatible with GCC in this regard.

ISTM that GetLinkerPath ought to produce the right name regardless and if it doesn't we can fix it to do so.

It is, but the current test will fail.

I'll be happy to adjust the test so that it matches all the right names, or so that it's restricted to only running on the targets where we know what the names might be. Can you suggest how to do that?

@MaskRay
Copy link
Member

MaskRay commented Sep 19, 2023

Can you comment on what projects need this? Can't we fix the projects instead? And what do they do with the linker path? Why don't they invoke the clang driver to run a link action?

They are legion. It comes from autoconf checks for libtool. It doesn't really matter why they're doing it. They are doing it and it will be years before they can all be changed. If you want to use Clang as the compiler for random open source code, it needs to be compatible with GCC in this regard.

Do your have some examples of such projects? As mentioned, I know multiple lld based distributions and they don't find clang -fuse-ld=ld --print-prog-name=ld not behave like GCC a problem. If you think there are many and existing distributions haven't detected them, I'd like to know the project.

BTW: if you make ld a symlink to lld or ld.lld, you'll pretty much not notice anything.

@petrhosek
Copy link
Member

petrhosek commented Sep 19, 2023

Do your have some examples of such projects?

I recently encountered this issue when compiling libffi. Note that this issue only manifests when there's no ld in PATH.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants