Clang libtooling可以';找不到stddef.h或其他标题

Clang libtooling可以';找不到stddef.h或其他标题,clang,Clang,我正在编写一个工具来解析C族源代码项目,基本上遵循ubuntu 12.04上Clang3.4(Trunk192426)上的这两个教程 基于,它说我可以通过-p传递compile\u commands.json,但是,如果我只键入$./main-p[path of compile\u commands.json],它会抱怨缺少位置参数。似乎我仍然需要将所有文件名作为参数传递,如果项目非常庞大,这是不实际的。我希望它可以简单地解析compile\u commands.json中指定的所有文件,而不必

我正在编写一个工具来解析C族源代码项目,基本上遵循ubuntu 12.04上Clang3.4(Trunk192426)上的这两个教程

基于,它说我可以通过
-p
传递
compile\u commands.json
,但是,如果我只键入
$./main-p[path of compile\u commands.json]
,它会抱怨缺少位置参数。似乎我仍然需要将所有文件名作为参数传递,如果项目非常庞大,这是不实际的。我希望它可以简单地解析
compile\u commands.json
中指定的所有文件,而不必询问,但无法找到如何打开它

因为我找不到做任何自定义事情的教程,所以我改用class。对于
VisitStmt
VisitDecl
VisitType
,有一个虚拟访问者返回
true
,因此我将跳过它。
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;
}
===更新===

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

因此,我的问题归结为当我有一个compile_commands.json时,如何将这些选项从“铿锵-####传递到LibTooling?我应该为每个要分析的文件调用shell命令吗

==更新====


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

有人回复我说编译数据库应该是独立的。首先,我需要确保compile_commands.json是使用clang生成的,我可以使用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没有找到解决方法。

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

[]

在“提示”部分

他们提到默认的include路径是

$(dirname /path/to/tool)/../lib/clang/3.3/include
这里的想法似乎是,您的工具应该是从bin目录执行的,而bin目录也包含了clang可执行文件本身。通常,这将是一个系统目录,因此从中往上一个将有一个lib目录,其中包含
clang/3.4/includ
e目录。因此,我手动将
$(which clang)…/lib/clang/3.4/include
包含到解析器中。在python中,这类似于

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

这导致
翻译单元.diagnostics
是一个空列表。

在我的例子中,我在Ubuntu上安装了clang tidy,但没有安装clang。我遇到了类似的问题,当我对compile\u commands.json调用clang tidy时,stddef.h找不到。在我的例子中,原因是,
clangtidy
基于llvm版本7,而
clang++
版本基于llvm版本4.0,在将clangtidy更改为正确的版本之后,问题消失了。

请为您的工具和compile命令的第一个参数使用匹配的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();
std::vector Args{/home/theuser/.local/llvm-8.0.0/bin/clang-8“,“-c”,“a.cpp”};
llvm::IntrusiveRefCntPtr文件管理器(新的clang::fileManager(clang::FileSystemOptions());
工具::工具调用调用器(Args,newblankAction(),fileManager.get());
run();

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

Spot on!让你想知道为什么
clang
不是一个
clang-tidy
依赖项-后者可能在没有前者的情况下运行,但如果没有它,你就无法真正使用它…谢谢!我也有同样的问题,就是使用clang-tidy6和clang++-9。升级到clang-tidy-9解决了这个问题。
  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();