Jokab
Jokab

Reputation: 2936

Coverity scan skips all commands due to gcc -M option and scans nothing

I am having some trouble using Coverity with my C/C++ code.

When I run cov-build with --debug-flags translate-phases, I get output that suggests that all compiler invocations are skipped because of the -M flag. Essentially (reading build-log.txt after running cov-build:

ARGS after split: -M -MP <other commands follow>

Then the next line:

Skipping command line '-M -MP <other commands follow>' because argument '-M' is a skip argument 

This seems to result in Coverity not compiling any of my files and therefore produces no output.

Does Coverity simply not support the -M flag? Are there any workarounds?

For completeness I am using Coverity Scan 7.6.1 and gcc 4.8.2.

Upvotes: 1

Views: 1715

Answers (2)

Jokab
Jokab

Reputation: 2936

I figured out the answer about two hours ago.

For me, the cov-configure command generated five different configuration artifacts (where 2-5 are folders):

  1. Main configuration file
  2. g++-config-0
  3. g++-config-1
  4. gcc-config-0
  5. gcc-config-1

I don't really know why it decided to give me four folders, two for each type of compiler, but anyway.

In each of these four folders was a coverity_configuration.xml file. All of these contained the lines:

<skip_arg>-M</skip_arg>
<skip_arg>-MM</skip_arg>

Reading up on this tag, it tells the cov-translate command (called from cov-build) to not send to cov-emit any compiler invocation that passes either of those arguments. Removing those two lines solved everything.

I can't say why those two tags were put there by default. But it works now.

Upvotes: 0

Paolo Bonzini
Paolo Bonzini

Reputation: 1930

Passing -M to the compiler implies -E, i.e. run the preprocessor only. Because of this, Coverity does not do anything at all here. However, there's no reason why it shouldn't proceed with the second invocation of gcc that does not include -M and hence does compilation.

That said, there are better ways to automatically generate dependencies than the old -M flag; in particular newer versions of GCC allow you to do compilation and generation of dependencies with a single command. The relevant makefile idiom is this:

# the magic is all in this line
DEPFLAGS     = -MMD -MP -MT $@ -MF $(@D)/$(*F).d

# remember to change the spaces to tab here!
# anyway this is just an example.  All you need to do is to add
# $(DEPFLAGS) to your usual C compilation rule.
.c.o:
        $(CC) $(CFLAGS) $(CPPFLAGS) $(DEPFLAGS) -c -o $@ $<

# same for C++
.cc.o:
        $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(DEPFLAGS) -c -o $@ $<

# at the end of the makefile, include the dependencies
-include $(wildcard *.d)

You may need something like -include $(wildcard */*.d *.d) if you have a nonrecursive Makefile. But this part probably will be very similar to your existing rules.

This is described here and the linked web page will provide more information on automatic dependency generation than you thought could exist.

Upvotes: 1

Related Questions