clang-cl: Add /showFilenames option (PR31957)
ClosedPublic

Authored by hans on Tue, Oct 2, 2:08 AM.

Details

Summary

Add a /showFilenames option for users who want clang to echo the currently compiled filename. MSVC does this echoing by default, and it's useful for showing progress in build systems that doesn't otherwise provide any progress report, such as MSBuild.

Diff Detail

Repository
rL LLVM
hans created this revision.Tue, Oct 2, 2:08 AM
steveire added inline comments.Tue, Oct 2, 5:36 AM
lib/Frontend/CompilerInvocation.cpp
792 ↗(On Diff #167893)

I'll have to keep a patch around anyway for myself locally to remove this condition. But maybe someone else will benefit from this.

What do you think about changing CMake to so that this is passed by default when using Clang-CL?

zturner added inline comments.Tue, Oct 2, 5:51 AM
lib/Frontend/CompilerInvocation.cpp
792 ↗(On Diff #167893)

Do you mean llvms cmake? Or cmake itself? Which generator are you using?

hans added inline comments.Tue, Oct 2, 6:18 AM
lib/Frontend/CompilerInvocation.cpp
792 ↗(On Diff #167893)

Can't you just configure your build to pass the flag to clang-cl?

I suppose CMake could be made to do that by default when using clang-cl versions that support the flag and using the MSBuild generator, but that's for the CMake community to decide I think. Or perhaps our VS integration could do that, but it gets tricky because it needs to know whether the flag is supported or not.

steveire added inline comments.Tue, Oct 2, 6:37 AM
lib/Frontend/CompilerInvocation.cpp
792 ↗(On Diff #167893)

I mean upstream cmake. My suggestion is independent of the generator, but it would depend on what Brad decides anyway. I don't intend to implement it, just report it.

I only have one clang but I have multiple buildsystems, and I don't want to have to add a new flag too all of them. In each toplevel CMakeLists everyone will need this to make use of the flag:

# Have to remember to use "${CMAKE_CXX_SIMULATE_ID}" instead of 
# Undecorated "CMAKE_CXX_SIMULATE_ID" because there is a 
# variable named "MSVC" and
# the way CMake variables and the "if()" command work requires this. 
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang 
        AND ${CMAKE_CXX_SIMULATE_ID} STREQUAL MSVC)
    # CMake does not have explicit Clang-CL support yet.
    # It should have a COMPILER_ID for it.
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /showFilename")
    # etc
endif()

Upstream CMake can have the logic to add the flag instead.

thakis accepted this revision.Tue, Oct 2, 6:41 AM

Looks good. If this is passed and we invoke lld-link, should we give that a similar flag and pass that to lld-link as well? I think link.exe also prints its outputs.

include/clang/Driver/CLCompatOptions.td
163 ↗(On Diff #167893)

Can you add /showFilenames- (a no-op) too, for symmetry?

This revision is now accepted and ready to land.Tue, Oct 2, 6:41 AM

Canyou add a test that demonstrates that multiple input files on the command line will print all of them? Also does this really need to be a cc1 arg? Why not just print it in the driver?

zturner added inline comments.Tue, Oct 2, 8:48 AM
lib/Frontend/CompilerInvocation.cpp
792 ↗(On Diff #167893)

But then what if you don’t want it? There would be no way to turn it off. I don’t think it’s a good fit for cmake

792 ↗(On Diff #167893)

Yes, and actually for this reason i was wondering if we can do it without a flag at all. What if we just set an magic environment variable? It handles Stephen’s use case (he can just set it globally), and MSBuild (we can set it in the extension).

rnk accepted this revision.Tue, Oct 2, 9:11 AM

I support continuing our practice of being silent by default, and not implementing anything like the noisy default version banner printing that MSVC does, or this filename printing. I think setting this flag is something for cmake or the VS integration to do. Only someone who knows something about the progress printing model can set it correctly.

lib/Driver/ToolChains/Clang.cpp
3533–3534 ↗(On Diff #167893)

Is a -cc1 flag actually necessary? I was imagining we'd print it in the driver before we launch the compile job.

steveire added inline comments.Tue, Oct 2, 11:30 AM
lib/Frontend/CompilerInvocation.cpp
792 ↗(On Diff #167893)

But then what if you don’t want it? There would be no way to turn it off.

Oh, I thought that the last flag would dominate. ie, if cmake generated /showFilename and the user adds /showFilename-, then you would end up with

clang-cl.exe /showFilename /showFilename-

and it would not be shown. I guess that's not how it works.

Maybe users want to not show it, but not seeing the filename is a surprising first-time experience when porting from MSVC to clang-cl using Visual Studio.

However, I'll just drop out of the discussion and not make any bug to CMake. If anyone else feels strongly, they can do so.

Thanks!

zturner added inline comments.Tue, Oct 2, 11:40 AM
lib/Frontend/CompilerInvocation.cpp
792 ↗(On Diff #167893)

Right, but if we update the VS Integration Extension so that MSBuild specifies the flag (or sets the environment variable, etc), then any time you use MSBuild (even if not through the IDE) you would get the output, so to the user it would look no different.

hans added a comment.Thu, Oct 4, 5:11 AM

Canyou add a test that demonstrates that multiple input files on the command line will print all of them?

Will do.

Also does this really need to be a cc1 arg? Why not just print it in the driver?

Yeah, I'll give printing from the driver a try.

include/clang/Driver/CLCompatOptions.td
163 ↗(On Diff #167893)

Will do. Actually not just a no-op, but the last option should win.

lib/Driver/ToolChains/Clang.cpp
3533–3534 ↗(On Diff #167893)

Yeah, that's probably better, but will take a bit more work to keep track of if and what to print in the compile job. I'll give it a try.

lib/Frontend/CompilerInvocation.cpp
792 ↗(On Diff #167893)

I think we should avoid magic environment variables as much as possible.

zturner added a subscriber: rnk.Thu, Oct 4, 5:37 AM

I agree magic environment variables are bad, but without it we don’t
address the only current actual use we have for this, which is making the
vs integration print filenames. Detecting compiler version from inside the
integration is hard, but with an environment variable it’s very easy to
solve.

I’m not against a flag as the supported way, but I think we should also
have some backdoor into this functionality, because if we’re not going to
satisfy the only known use case, then maybe it’s better to not even do it
at all.

I agree magic environment variables are bad, but without it we don’t
address the only current actual use we have for this, which is making the
vs integration print filenames. Detecting compiler version from inside the
integration is hard

We need some solution to this anyhow; e.g. say "this now requires clang 8.0", or have a clang version dropdown in the UI (which defaults to the latest release), or something. We can't add an env var for every future flag that the vs integration might want to use.

I agree magic environment variables are bad, but without it we don’t
address the only current actual use we have for this, which is making the
vs integration print filenames. Detecting compiler version from inside the
integration is hard

We need some solution to this anyhow; e.g. say "this now requires clang 8.0", or have a clang version dropdown in the UI (which defaults to the latest release), or something. We can't add an env var for every future flag that the vs integration might want to use.

But it is very hard to automatically detect the version from the integration. I tried this and gave up because it was flaky. So sure, we can present a drop-down in the UI, but it could be mismatched, and that would end up creating more problems than it solves.

Right now we have exactly 1 use case for showing filenames from clang-cl, and there's no good way to satisfy that use case with a command line option.

I agree that we can't add an environment variable for every future flag that the VS integration might want to use, but until that happens, YAGNI. And if and when we do need it, if we manage to come up with a solution to the problem, we can delete support for the environment variable and make it use the new method.

rnk added a comment.Thu, Oct 4, 11:43 AM

It doesn't address the version skew issue, but my blanket argument against any new environment variable is the existance of things like _CL_ and CCC_OVERRIDE_OPTIONS. You can set any compiler flag you want from the environment, so we should standardize on one way of setting options: flags.

hans updated this revision to Diff 168999.Wed, Oct 10, 6:50 AM

Here's a version now using cc1 flags, but printing directly from the driver. Please take a look.

rnk accepted this revision.Wed, Oct 10, 1:40 PM

lgtm

lib/Driver/Job.cpp
319 ↗(On Diff #168999)

Huh, a -cc1 action can have multiple inputs? Go figure.

test/Driver/cl-showfilenames.c
7–8 ↗(On Diff #168999)

I think it'd be nice to have the test show that diagnostics come out interleaved between the filenames. You can use #pragma message in the input files or something else to create warnings.

hans added inline comments.Thu, Oct 11, 2:57 AM
test/Driver/cl-showfilenames.c
7–8 ↗(On Diff #168999)

Good idea, thanks.

This revision was automatically updated to reflect the committed changes.