14

我正在编写一个工具来解析 C 系列源代码项目,基本上遵循ubuntu 12.04 上的 clang 3.4(主干 192426)上的这两个教程1 2 。

根据官方教程,它说我可以通过compile_commands.json-p但是,如果我只输入$ ./main -p [path of compile_commands.json],它会抱怨缺少位置参数。似乎我仍然需要将所有文件名作为参数传递,如果项目真的很大,这是不切实际的。我更喜欢它可以简单地解析所有指定的文件compile_commands.json而无需询问,但无法找到如何打开它。

由于我找不到CommonOptionsParser的教程来做任何自定义的事情,我使用CompilationDatabase类代替。有一个假访客返回trueVisitStmt所以我将跳过它VisitDeclVisitTypemain功能非常简单:

int main(int argc, const char **argv) {
    string errorMsg = "";
    CompilationDatabase *cd = CompilationDatabase::autoDetectFromDirectory (argv[1], errorMsg);
    ClangTool Tool(*cd, cd->getAllFiles());

    int result = Tool.run(newFrontendActionFactory<ExampleFrontendAction>());

    return result;
}

我选择opencv解析,因为使用 cmake 保证了compile_commands.json(对吗?)的正确性。但是,出现了很多错误(最后附上)。LibTooling 抱怨它找不到stdarg.hstddef.h也没有emmintrin.h。这是 clang 的常见问题解答,但它说明了为什么会发生这种情况,但没有说明在使用 libtooling 时如何解决这个问题。传递clang -###for clang 的所有参数可以解决这个问题,但是如何在使用 libtooling 时传递这些参数?

# include <stdarg.h>
          ^
1 error generated.
Error while processing /home/jcwu/repos/opencv/3rdparty/openexr/IlmImf/ImfCompressionAttribute.cpp.
In file included from /home/jcwu/repos/opencv/3rdparty/libjpeg/jmemansi.c:16:
/home/jcwu/repos/opencv/3rdparty/libjpeg/jinclude.h:35:10: fatal error: 'stddef.h' file not found
#include <stddef.h>
         ^
1 error generated.
Error while processing /home/jcwu/repos/opencv/3rdparty/libjpeg/jmemansi.c.
error: no suitable precompiled header file found in directory '/home/jcwu/repos/opencv/modules/legacy/precomp.hpp.gch'
1 error generated.
Error while processing /home/jcwu/repos/opencv/modules/legacy/src/hmmobs.cpp.
In file included from /home/jcwu/repos/opencv/3rdparty/libwebp/enc/quant.c:17:
In file included from /home/jcwu/repos/opencv/3rdparty/libwebp/enc/../dsp/../enc/vp8enci.h:17:
/usr/include/string.h:34:10: fatal error: 'stddef.h' file not found
#include <stddef.h>
         ^
1 error generated.
Error while processing /home/jcwu/repos/opencv/3rdparty/libwebp/enc/quant.c.
In file included from /home/jcwu/repos/opencv/modules/imgproc/opencv_test_imgproc_pch_dephelp.cxx:1:
In file included from /home/jcwu/repos/opencv/modules/imgproc/test/test_precomp.hpp:12:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/iostream:40:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/ostream:40:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/ios:39:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/iosfwd:42:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/bits/postypes.h:42:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/cwchar:46:
/usr/include/wchar.h:40:11: fatal error: 'stdarg.h' file not found
# include <stdarg.h>

==== 更新 ====

阅读 CommonOptionsParser.cpp 源代码。它使用 FixedCompilationDatabase 通过 -- 之后的参数来猜测 CompilationDatabase,然后在 -- 之前传递参数以用于自定义(仅 CommonOptionParser 中的 -p)选项。在我的情况下 compile_commands.json 是必需的,所以我可以跳过使用 CommonOptionsParser。

因此,当我有 compile_commands.json 时,我的问题减少到如何将这些选项从“clang -###”传递给 LibTooling?我应该为每个要解析的文件调用 shell 命令吗?

==== 更新 ====

我认为修改 compile_commands.json 可能更容易。我不确定为什么 CMake 生成的 compile_commands.json 不会正确包含我的系统头文件文件夹,因为 CMakeList.txt 生成的 Makefile 可以正确编译,为什么 compile_commands.json 会错过很多东西。

4

5 回答 5

9

我在使用 python 绑定时遇到了类似的问题。

[<Diagnostic severity 4, location <SourceLocation file '/usr/include/stdio.h', line 33, column 11>, spelling "'stddef.h' file not found">]

在“提示”部分中

http://clang.llvm.org/docs/LibTooling.html

他们提到默认的包含路径是

$(dirname /path/to/tool)/../lib/clang/3.3/include

这里的想法似乎是,预计您的工具正在从 bin 目录执行,该目录还包含 clang 可执行文件本身。通常,这将是一个系统目录,因此从该目录上移一个将具有包含clang/3.4/include 目录的 lib 目录。所以我手动包含$(which clang)../lib/clang/3.4/include到解析器中。在 python 中,这看起来像

translation_unit = index.parse("test.cc",["-I/home/archgoon/usr/local/lib/clang/3.4/include"])

这导致translation_unit.diagnostics成为一个空列表。

于 2014-04-26T18:27:58.957 回答
9

就我而言,我在安装 clang-tidy 但在 Ubuntu 上也没有 clang 时遇到错误。

于 2017-04-09T14:02:32.567 回答
1

有人回复我说编译数据库应该是自包含的。首先,我需要确保使用 clang 生成 compile_commands.json,并且我可以使用 clang 来构建 opencv。

我设置了这些环境变量

export CC=/home/jcwu/repos/llvm-release/Release/bin/clang 
export CXX=/home/jcwu/repos/llvm-release/Release/bin/clang++ 
export C_INCLUDE_PATH=/usr/local/include:/home/jcwu/repos/llvm-release/Release/lib/clang/3.4/include:/usr/include/x86_64-linux-gnu:/usr/include  # these are from clang -v -c files.cpp 
export CPLUS_INCLUDE_PATH=/usr/local/include:/home/jcwu/repos/llvm-release/Release/lib/clang/3.4/include:/usr/include/x86_64-linux-gnu:/usr/include 

然后重新生成compile_commands.json,它可以找到stddef.h但出现了新问题

[ 31%] Building CXX object modules/ts/CMakeFiles/opencv_ts.dir/src/ts.cpp.o 
In file included from /home/jcwu/repos/opencv/modules/ts/src/ts.cpp:116: 
/usr/include/setjmp.h:60:12: error: conflicting types for '__sigsetjmp' 
extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __THROWNL; 
           ^ 
/usr/include/pthread.h:727:12: note: previous declaration is here 
extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROW; 
           ^ 
1 error generated. 
make[2]: *** [modules/ts/CMakeFiles/opencv_ts.dir/src/ts.cpp.o] Error 1 
make[1]: *** [modules/ts/CMakeFiles/opencv_ts.dir/all] Error 2 
make: *** [all] Error 2 

由于类型冲突或两个系统头文件,我无法使用 clang 构建 opencv。还没有想出如何解决这个问题。

于 2013-10-30T03:55:20.433 回答
1

当我针对 compile_commands.json 调用 clang-tidy 时,我遇到了类似的问题,这会导致找不到 stddef.h。在我的情况下,原因是clang-tidy基于 llvm 版本7clang++版本是基于 llvm 版本4.0的,将 clang-tidy 更改为正确的版本后,问题就消失了。

于 2019-01-29T02:18:57.477 回答
0

请为您的工具使用匹配的 clang 版本和编译命令的第一个参数(并使用正确的路径)。

例如:

  std::vector<std::string> Args {"/home/theuser/.local/llvm-8.0.0/bin/clang-8", "-c", "a.cpp"};
  llvm::IntrusiveRefCntPtr<clang::FileManager> fileManager(new clang::FileManager(clang::FileSystemOptions()));
  clang::tooling::ToolInvocation invoker(Args, new BlankAction(), fileManager.get());
  invoker.run();

如果你使用 clang 8.0 的库来构建这个工具,它会成功。如果您使用其他版本(clang 3.6 等),可能会导致此错误。

于 2019-10-10T07:59:09.650 回答