ccache and 'unused argument' warning

A user who uses ccache reported that it is apparently doing something that causes it to emit tons of "argument unused during compilation warnings". A typical invocation is something like this:

ccache clang++ -m32 -mmmx -msse -pipe -march=pentium-m -I/usr/include/malloc -fasm-blocks -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 -Wno-invalid-offsetof -Wno-unknown-pragmas -Wno-unused-parameter -Wno-reorder -Wno-unused-value -Wno-missing-field-initializers -Wno-sign-compare -Wno-invalid-offsetof -Wno-write-strings -gdwarf-2 -g2 -O3 -fno-strict-aliasing -DNDEBUG -DGNUC -DPOSIX -D_OSX -DOSX -Ifoo -c foo.cpp -o foo.o

which produces warnings like this:
clang: warning: argument unused during compilation: '-c'
clang: warning: argument unused during compilation: '-I/usr/include/malloc'
clang: warning: argument unused during compilation: '-isysroot /Developer/SDKs/MacOSX10.5.sdk'
clang: warning: argument unused during compilation: '-DNDEBUG'
clang: warning: argument unused during compilation: '-DGNUC'
clang: warning: argument unused during compilation: '-DPOSIX'
clang: warning: argument unused during compilation: '-D_OSX'
clang: warning: argument unused during compilation: '-DOSX'
clang: warning: argument unused during compilation: '-Ifoo'

etc. This is apparently local to something that ccache is doing: it must be running clang multiple times, one with some funny options. The user was alarmed because he didn't think that clang had implemented such exotic options as -D and -I :slight_smile: due to these warnings.

The question is: is this a ccache bug, or should we hack clang somehow to work better with ccache? I don't use ccache or know anything about it, so I don't really have an opinion here.

-Chris

… wait, ccache support clang? that’s good news :slight_smile:

I have no idea, apparently so?

-Chris

Chris Lattner <clattner-2kanFRK1NckAvxtiuMwx3w@public.gmane.org> writes:

I have no idea, apparently so?

It supports any compiler that takes a similar command-line to gcc (I
think -E is the important flag).

From the manual:

   HOW IT WORKS

   The basic idea is to detect when you are compiling exactly the same
   code a 2nd time and use the previously compiled output. You detect
   that it is the same code by forming a hash of:

   * the pre-processor output from running the compiler with -E
   * the command line options
   * the real compilers size and modification time
   * any stderr output generated by the compiler

   These are hashed using md4 (a strong hash) and a cache file is
   formed based on that hash result. When the same compilation is done
   a second time ccache is able to supply the correct compiler output
   (including all warnings etc) from the cache.

   ccache has been carefully written to always produce exactly the same
   compiler output that you would get without the cache. If you ever
   discover a case where ccache changes the output of your compiler then
   please let me know.

So it works by running the preprocessor to make sure the preprocessed
source hasn't changed. I have a feeling it might end up just doing the
compile if something's changed, so might end up repeating the
preprocessing.

The assumption seems to be that preprocessing is relatively cheap, which
(IIUC) isn't valid for clang, so perhaps ccache (as it exists now) just
isn't worth using?

ccache runs the compiler twice: First with -E to create a preprocessed file, second it compiles the preprocessed file if it doesn't have a matching object file in its cache.

On the first run, '-c' is unused because -E was added.
On the second run, '-I', '-D', and '-isysroot' are ignored because the preprocessor isn't run.

I am guessing that ccache doesn't know what clang is, so it doesn't remove any options, just to be sure.

/jakob

The tradeoffs change: clang's preprocessor is about 2x faster than GCC's, so preprocessing does remain relatively cheap in the cases where it is also cheap for gcc. However, if your .c file includes a ton of headers and has relatively little code, you can end up burning more time preprocessing than actually compiling. This is independent of what compiler you use.

-Chris

Jakob Stoklund Olesen <stoklund@2pi.dk> writes:

ccache runs the compiler twice: First with -E to create a preprocessed
file, second it compiles the preprocessed file if it doesn't have a
matching object file in its cache.

On the first run, '-c' is unused because -E was added. On the second
run, '-I', '-D', and '-isysroot' are ignored because the preprocessor
isn't run.

I am guessing that ccache doesn't know what clang is, so it doesn't
remove any options, just to be sure.

This makes sense. In my own use of clang with ccache I've noticed that
it complains about -c being unused for each source file it compiles.

I don't think ccache knows what gcc is either, but gcc doesn't complain
about -c being unused when you do `gcc -c -E foo.c`.

Hi Chris,

I plan to reduce some of the noise from clang's "warning: argument
unused" by trying to be a bit smarter about when the warning would be
interesting. That should reduce some of the noise, although perhaps
not all. This work is a low priority for me though...

For now, one can use -Qunused-arguments to suppress the warning.

- Daniel