This is an archive of the discontinued LLVM Phabricator instance.

Propagate -fdiagnostics-color to LLD.
Needs ReviewPublic

Authored by ruiu on Dec 8 2016, 5:15 PM.

Details

Reviewers
hans
Summary

Some build systems such as Ninja sets -fdiagnostics-color to Clang
command line so that errors are displayed in color. However, linker
errors were displayed without color because the compiler driver
didn't pass that parameter to linkers.

This is a patch to set -color-diagnostics=all if a linker is LLD.
LLD supports that option and displays errors in color.

I'm not totally sure if this is the right place to add new code,
but it seems we have many copy-and-pasted code to construct a linker
command line in this file, and if I fixed each of them, I'd have had
to update more than 10 locations.

Event Timeline

ruiu updated this revision to Diff 80850.Dec 8 2016, 5:15 PM
ruiu retitled this revision from to Propagate -fdiagnostics-color to LLD..
ruiu updated this object.
ruiu added a reviewer: hans.
ruiu added a subscriber: llvm-commits.
hans added inline comments.Dec 9 2016, 8:37 AM
lib/Driver/Tools.cpp
234

Yes, this doesn't seem like exactly the right place, but maybe there is no better one. Perhaps we could add an "addCommonLinkerFlags" function?

286

This needs a test.

And can we get color diagnostics from lld-link.exe too? That would be nice.

rnk added a subscriber: rnk.Dec 9 2016, 8:47 AM
rnk added inline comments.
lib/Driver/Tools.cpp
283

nit: Clang's original spelling was -fcolor-diagnostics, which reads better in English. GCC made -fdiagnostics-color, which we added as an alias. It makes sense ontologically, but it doesn't read as well in a comment.

ruiu added inline comments.Dec 9 2016, 10:34 AM
lib/Driver/Tools.cpp
234

The other way of propagating this is to use an environment variable. Because we have control of both the compiler and the linker, we can make a change to LLD to interpret something like LLD_COLOR_DIAGNOSTICS=1 and set it in Clang.

The point is that in that way we can still have the exact same command line for bfd/gold/lld. What do you think?

hans added inline comments.Dec 9 2016, 10:40 AM
lib/Driver/Tools.cpp
234

I don't think Clang passes things via the environment to any other tool. I think passing a flag is better.

rsmith added a subscriber: rsmith.Dec 9 2016, 10:53 AM
rsmith added inline comments.
lib/Driver/Tools.cpp
284

I don't think this will work for -fuse-ld=$BINDIR/lld and the like. We also have code around Tools.cpp doing things like this:

const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
if (llvm::sys::path::filename(Exec) == "lld") {

and

const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
if (llvm::sys::path::stem(Exec).equals_lower("lld")) {

so detecting ld.lld here seems inconsistent. (Meanwhile, the above checks won't fire for -fuse-ld=lld, since that sets the linker path to .../ld.lld.)

I think it's time to factor out an isLinkerLLD function and use that to detect whether we're using lld.

ruiu added inline comments.Dec 9 2016, 11:01 AM
lib/Driver/Tools.cpp
284

What if a linker is just /usr/bin/ld? I want to detect if it's LLD or not, but it's not doable without running that command. (If we pass it via the environment, we can always set LLD_COLOR_DIAGNOSTICS=1 though.)

rsmith added inline comments.Dec 9 2016, 2:27 PM
lib/Driver/Tools.cpp
284

Maybe the best we can do is have each target tell us what it expects /usr/bin/ld to be, and/or readlink it and see if it is a symlink to a binary named lld. This doesn't seem like a very satisfying answer, though :(

We already pass some flags if we think we're running lld (for instance, -flavor gnu -target $TARGET); passing those through the environment doesn't seem ideal.

ruiu added a comment.Dec 12 2016, 3:21 PM

Nico suggested I make change to CMake instead of Clang so that CMake adds -Wl,-color-diagnostics if it detects the linker can accept that option. I think that makes sense, so I'll look into it.