我正在编写一个工具来解析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
VisitStmt
,VisitDecl
和VisitType
,因此我会跳过这一点。 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.h
,stddef.h
或emmintrin.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会错过很多东西。
答案 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等),则可能会导致此错误。