在构建期间捕获所有编译器调用和命令行参数

Capture all compiler invocations and command line parameters during build

我想要 运行 静态工具 C/C++(可能还有 Python、Java 等)代码分析,用于在帮助下构建的大型软件项目make。众所周知,make(或任何其他构建工具)为指定的源代码文件调用编译器和类似工具。也可以通过定义环境变量来控制编译,稍后通过其参数传递给编译器。

准确静态分析的关键是提供与传递给编译器的路径完全相同的定义和包含路径(基本上是所有 -D-I 参数)。这样,该工具将能够遵循编译器遵循的相同代码路径。

问题是,项目的高度复杂性意味着无法静态确定此类环境,因为不同的文件是使用不同的 defines/include 路径集和其他编译标志构建的。

这个想法是,应该能够以某种方式捕获编译器的单个调用,以及为每个输入文件传递给它的所有参数。有了这些信息并经过直接过滤(例如,无需知道 -O 优化级别或 -W 警告设置),应该可以为每个输入文件调用静态分析器defines/includes 仅用于该输入文件。

问题是:是否存在 tools/workflows 实现我所描述的想法的方法? 我最感兴趣的是 POSIX 系统的解决方案, 但也欢迎 Windows 的想法。

我自己想到的一些想法。

VERBOSE=true 是默认的 make 选项,用于显示带有所有参数的所有命令。例如,它也适用于 CMake。

您可能想看看 Coverity。他们将他们的工具附加到编译器以获取编译器接收到的所有内容。您可以覆盖环境变量 CCCXX 以首先收集所有内容,然后像往常一样调用编译器。

Linux编译参数的收集方式有以下几种:

  1. 覆盖环境 CC/CXX 变量。它用于 Clang Analyzer 的实用程序 scan-build。此方法仅适用于 Make 的简单项目。

  2. procfs - 有关进程的所有信息都存储在 /proc/PID/... 中。从磁盘读取是一个缓慢的过程,您可能无法接收有关构建的所有进程的信息。

  3. strace 实用程序(ptrace 库)。该实用程序的输出包含很多有用的信息,但需要进行复杂的解析,因为信息是随机写入的。如果您不使用许多线程来构建项目,这是一种收集有关进程信息的相当可靠的方法。用于PVS-Studio.

  4. JSON CMake 中的编译数据库。您可以使用定义 -DCMAKE_EXPORT_COMPILE_COMMANDS=On 获取所有编译参数。如果项目不依赖 non-standard 环境变量,这是一种可靠的方法。此外,CMake 的项目可能会编写错误并发出不正确的 Json,尽管这不会影响项目构建。 PVS-Studio.

  5. 支持
  6. Bear 实用程序(使用 LD_PRELOAD 的函数替换)。您可以获得任何项目的 JSON 数据库编译。但是如果没有环境变量,某些项目将无法 运行 分析器。此外,您不能将它用于已经使用 LD_PRELOAD 进行构建的项目。 PVS-Studio.

  7. 支持

正在为 PVS-Studio 收集有关在 Windows 中编译的信息:

  1. Visual Studio API获取标准工程的编译参数;

  2. MSBuild API获取标准项目的编译参数;

  3. Win API 获取任何编译过程的信息,例如,Windows 任务管理器就是这样做的。