【问题标题】:Coverity scan skips all commands due to gcc -M option and scans nothing由于 gcc -M 选项,Coverity 扫描跳过所有命令并且什么都不扫描
【发布时间】:2016-07-15 08:59:18
【问题描述】:

在我的 C/C++ 代码中使用 Coverity 时遇到了一些问题。

当我使用--debug-flags translate-phases 运行cov-build 时,我得到的输出表明由于-M 标志而跳过了所有编译器调用。本质上(运行cov-build后阅读build-log.txt

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

然后下一行:

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

这似乎导致 Coverity 不编译我的任何文件,因此不产生任何输出。

Coverity 是否根本不支持 -M 标志?有什么解决方法吗?

为了完整起见,我使用的是 Coverity Scan 7.6.1 和 gcc 4.8.2。

【问题讨论】:

  • 是的... Coverity 是一个很棒的工具,它有一些文档空白 :) 基于日志项 "... 参数 '-M' 是一个跳过参数...",我猜它不受支持(但它只是一个猜测)。大局观:为什么要让 Coverity 分析 Make 依赖项的规则输出?

标签: c++ gcc coverity


【解决方案1】:

-M 传递给编译器意味着-E,即只运行预处理器。因此,Coverity 在这里根本不做任何事情。但是,它没有理由不继续对不包含-Mgcc第二 次调用,因此会进行编译。

也就是说,有比旧的-M 标志更好的方法来自动生成依赖项;特别是较新版本的 GCC 允许您使用单个命令进行编译和生成依赖项。相关的makefile成语是这样的:

# 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)

如果你有一个非递归的 Makefile,你可能需要像 -include $(wildcard */*.d *.d) 这样的东西。但这部分可能与您现有的规则非常相似。

这被描述为here,链接的网页将提供比您想象的更多的关于自动依赖生成的信息。

【讨论】:

  • 虽然您的回答很有趣并且我感谢您,但我无权以任何方式更改构建过程的工作方式。所以不幸的是,这个答案并没有真正的帮助。
  • @Jokab 但是您的构建过程在-M 调用之后是否第二次执行GCC? (无论有没有cov-build,我都对答案感兴趣)。
【解决方案2】:

大约两个小时前我就知道了答案。

对我来说,cov-configure 命令生成了五个不同的配置工件(其中 2-5 是文件夹):

  1. 主配置文件
  2. g++-config-0
  3. g++-config-1
  4. gcc-config-0
  5. gcc-config-1

我真的不知道为什么它决定给我四个文件夹,每种类型的编译器两个,但无论如何。

这四个文件夹中的每一个都有一个coverity_configuration.xml 文件。所有这些都包含以下行:

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

阅读这个标签,它告诉cov-translate 命令(从cov-build 调用)不要向cov-emit 发送任何传递这些参数的任何编译器调用。删除这两行解决了所有问题。

我不能说为什么这两个标签默认放在那里。但现在可以了。

【讨论】:

  • 每个都有两个 - gcc 作为 C,gcc 作为 C++,g++ 作为 C,g++ 作为 C++
  • -Mskip_arg 因为使用 -M 的编译实际上不会编译任何内容。您需要后续的 real 编译,Coverity 将编译这些编译。这就是保罗的回答所说的。你做了干净的构建吗?也许只看到-M 调用的原因是因为您的所有构建工件都是最新的,因此make 确定不需要编译(但仍然需要-M 调用以确保依赖关系是最新的-日期)。
  • @Caleb 我总是做干净的构建。我正在使用的构建过程非常复杂,而且我在 C/C++ 构建过程中的经验不是很丰富,因此很难理解到底发生了什么。但无论如何,删除这两个标签会让 Coverity 看到我的代码,并且它现在可以工作了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 2014-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多