libtooling找不到stddef.h或其他头文件

时间:2013-10-28 18:40:22

标签: clang

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

根据offical tutorial,它说我可以通过compile_commands.json传递-p,但是,如果我只输入$ ./main -p [path of compile_commands.json],它会抱怨缺少位置参数。看起来我仍然需要将所有文件名作为参数传递,如果项目非常庞大,这是不切实际的。我更喜欢它可以简单地解析compile_commands.json中指定的所有文件而无需询问,但无法找到如何启用它。

由于我找不到CommonOptionsParser的教程来做任何自定义的事情,我改用CompilationDatabase类。有一位虚拟访问者返回true VisitStmtVisitDeclVisitType,因此我会跳过这一点。 main函数非常简单:

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 gaurantee compile_commands.json的正确性(对吧?)。但是,出现了很多错误(附在最后)。 LibTooling抱怨它无法找到stdarg.hstddef.hemmintrin.h。对于clang来说它是FAQ,但它说明了为什么会发生这种情况,但没有说明如何在使用libtooling时解决这个问题。为clang传递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会错过很多东西。

5 个答案:

答案 0 :(得分:7)

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

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

在&#34;提示&#34;

部分

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

他们提到默认包含路径是

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

这里的想法似乎是,您的工具正在从包含clang可执行文件本身的bin目录执行。通常情况下,这将是一个系统目录,因此从中获取一个目录将包含包含clang/3.4/includ e目录的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成为空列表。

答案 1 :(得分:6)

在我的情况下,我收到的错误是在Ubuntu上安装了clang-tidy而不是clang。

答案 2 :(得分: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。 Havne没有想出如何解决这个问题。

答案 3 :(得分:0)

我在针对compile_commands.json调用clang-tidy时遇到了类似的问题,未发现恐慌stddef.h。就我而言,原因是clang-tidy是基于llvm版本 7 ,而clang++是基于llvm版本< strong> 4.0 ,将clang-tidy更改为正确的版本后,问题消失了。

答案 4 :(得分:0)

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

例如:

  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等),则可能会导致此错误。