This is an archive of the discontinued LLVM Phabricator instance.

Omit path to lld binary from lld's error and warning diagnostics.
ClosedPublic

Authored by thakis on Jul 11 2018, 7:59 AM.

Details

Summary

lld currently prepends the absolute path to itself to every diagnostic it emits. This path can be longer than the diagnostic, and makes the actual error message hard to read.

There isn't a good reason for printing this path: if you want to know which lld you're running, pass -v to clang – chances are that if you're unsure of this, you're not only unsure when it errors out. Some people want an indication that the diagnostic is from the linker though, so instead print just the basename of the linker's path.

Before:

$ out/bin/clang -target x86_64-unknown-linux -x c++ /dev/null -fuse-ld=lld 
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: cannot open crt1.o: No such file or directory
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: cannot open crti.o: No such file or directory
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: cannot open crtbegin.o: No such file or directory
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: unable to find library -lgcc
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: unable to find library -lgcc_s
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: unable to find library -lc
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: unable to find library -lgcc
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: unable to find library -lgcc_s
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: cannot open crtend.o: No such file or directory
/Users/thakis/src/llvm-mono/out/bin/ld.lld: error: cannot open crtn.o: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)

After:

$ out/bin/clang -target x86_64-unknown-linux -x c++ /dev/null -fuse-ld=lld 
ld.lld: error: cannot open crt1.o: No such file or directory
ld.lld: error: cannot open crti.o: No such file or directory
ld.lld: error: cannot open crtbegin.o: No such file or directory
ld.lld: error: unable to find library -lgcc
ld.lld: error: unable to find library -lgcc_s
ld.lld: error: unable to find library -lc
ld.lld: error: unable to find library -lgcc
ld.lld: error: unable to find library -lgcc_s
ld.lld: error: cannot open crtend.o: No such file or directory
ld.lld: error: cannot open crtn.o: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)

(The path is still printed for log messages.)

Diff Detail

Event Timeline

thakis created this revision.Jul 11 2018, 7:59 AM
ruiu added a comment.Jul 11 2018, 10:52 AM

I think we should at least include "ld.lld: " part in the error message, because without that, it is sometimes hard to identify what command is emitting an error in a long build log.

I think we should at least include "ld.lld: " part in the error message, because without that, it is sometimes hard to identify what command is emitting an error in a long build log.

+1 – it's useful to be able to immediately identify linker errors.

Do you plan to do something similar for lld-link as well?

ruiu added a comment.Jul 11 2018, 11:04 AM

How about changing the Clang driver so that it invokes a linker using a relative path instead of an absolute one when appropriate?

Thanks for taking a look!

I think we should at least include "ld.lld: " part in the error message, because without that, it is sometimes hard to identify what command is emitting an error in a long build log.

In what cases? clang doesn't prepend its errors with "clang:" (except for driver-level diags) either. For failed build steps, most build tools output the failing build step above the error so it's clear from context where the error comes from.

I see how this is is useful in the abstract, but I can't think of concrete examples (it's well possible I'm just lacking imagination), so I thought not printing anything is the best approach: If there's some concrete case where it helps, we'll learn about it and can add something back, and if there isn't then we end up with easier to read output. If we include some prefix and it's not needed, we'll always be stuck with it.

I think we should at least include "ld.lld: " part in the error message, because without that, it is sometimes hard to identify what command is emitting an error in a long build log.

+1 – it's useful to be able to immediately identify linker errors.

Do you plan to do something similar for lld-link as well?

This patch here modifies lld-link's behavior as well.

How about changing the Clang driver so that it invokes a linker using a relative path instead of an absolute one when appropriate?

On Windows, build systems usually call the linker directly, instead of through the driver. That path can still be quite long. (Also, see above.)

ruiu added a comment.Jul 11 2018, 1:06 PM

Thanks for taking a look!

I think we should at least include "ld.lld: " part in the error message, because without that, it is sometimes hard to identify what command is emitting an error in a long build log.

In what cases? clang doesn't prepend its errors with "clang:" (except for driver-level diags) either. For failed build steps, most build tools output the failing build step above the error so it's clear from context where the error comes from.

I see how this is is useful in the abstract, but I can't think of concrete examples (it's well possible I'm just lacking imagination), so I thought not printing anything is the best approach: If there's some concrete case where it helps, we'll learn about it and can add something back, and if there isn't then we end up with easier to read output. If we include some prefix and it's not needed, we'll always be stuck with it.

If you invoke the linker directly, you can just search for the linker name in a log and find an error, but if you do that through the compiler driver, is it easy to determine whether it's a link error or not, I guess. I don't a good example in hand, but the first thing I usually do to search for a link error is to search for "lld" after Ctrl-F. It's handy.

As to not printing out anything, I believe clang's behavior is somewhat unusual, as most command usually includes argv[0] in their error messages. It feels like we probably should follow the usual convention than clang.

Maybe printing out the basename of argv[0] could get the right balance. What do you think?

Maybe printing out the basename of argv[0] could get the right balance. What do you think?

I'm in favor of this. It's what gcc, ld.bfd, and ld.gold appear to do as well, so there's some precedent.

Actually, I lied; bfd and gold appear to print their full path. gcc does print the basename though, and that seems like a good compromise.

thakis updated this revision to Diff 156486.Jul 20 2018, 7:30 AM
thakis edited the summary of this revision. (Show Details)

print basename

Ok, basename is already a big improvement, so let's start there :-)

While finding the filename() function, I noticed that COFF/InputFiles.cpp could use it for slightly simpler code as well. If this change looks fine to you, I'll land it as 2 commits (one for the log message change, and one for the InputFiles.cpp simplification).

ruiu accepted this revision.Jul 20 2018, 2:56 PM

LGTM

This revision is now accepted and ready to land.Jul 20 2018, 2:56 PM
thakis closed this revision.Jul 20 2018, 4:14 PM

r337633 and r337634, thanks!