【问题标题】:libtooling can't find stddef.h nor other headerslibtooling 找不到 stddef.h 或其他头文件
【发布时间】:2013-10-28 18:40:21
【问题描述】:

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

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

由于我找不到 CommonOptionsParser 的教程来做任何自定义的事情,我改用 CompilationDatabase 类。有一个虚拟访客返回trueVisitStmtVisitDeclVisitType,所以我将跳过它。 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保证了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 会错过很多东西。

【问题讨论】:

    标签: clang


    【解决方案1】:

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

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

    在“提示”部分中

    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 成为一个空列表。

    【讨论】:

      【解决方案2】:

      在我的情况下,我在安装 clang-tidy 但在 Ubuntu 上没有 clang 时遇到错误。

      【讨论】:

      • 看准了!让您想知道为什么 clang 不是 clang-tidy 依赖项 - 后者可能在没有前者的情况下 运行,但如果没有它,您将无法真正使用它...
      【解决方案3】:

      有人回复我说编译数据库应该是自包含的。首先我需要确保 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。 还没想好怎么解决。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 谢谢!我有同样的问题,正在使用 clang-tidy6 和 clang++-9。升级到 clang-tidy-9 解决了这个问题。
        【解决方案5】:

        请为您的工具使用匹配的 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等),可能会导致此错误。

        【讨论】:

          猜你喜欢
          • 2015-01-11
          • 1970-01-01
          • 2019-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多