【问题标题】:Cannot use libclang with Qt无法将 libclang 与 Qt 一起使用
【发布时间】:2013-07-30 23:05:03
【问题描述】:

当我尝试在 Qt 应用程序中使用 libclang 时遇到了一个奇怪的错误。

test.cpp

#include <QApplication>
#include <QMainWindow>

#include <clang-c/Index.h>

int main (int argc, char *argv[]) {
    QApplication a(argc, argv);

    QMainWindow w;
    w.show();

    CXIndex index = clang_createIndex(0, 0);
    Q_UNUSED(index)

    return a.exec();
}

test.pro

QT += core widgets

TARGET = test
TEMPLATE = app

SOURCES += test.cpp

LIBS += -lclang

Shell 命令和输出:

$ ls
test.cpp test.pro
$ qmake
$ make
g++ -c -pipe -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/lib/qt/mkspecs/linux-g++ -I. -I/usr/include/qt -I/usr/include/qt/QtWidgets -I/usr/include/qt/QtGui -I/usr/include/qt/QtCore -I. -o test.o test.cpp
g++ -Wl,-O1,--sort-common,--as-needed,-z,relro -Wl,-O1 -o test test.o   -lclang -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread 
$ ./test
Two passes with the same argument (-alloca-hoisting) attempted to be registered!
Segmentation fault

如果我在不使用 qmake 的情况下手动运行 g++,我会得到同样的错误:

$ g++ -fPIE test.cpp -o test -I/usr/include/qt -I/usr/include/qt/QtWidgets -lQt5Widgets -lclang
$ ./test
Two passes with the same argument (-alloca-hoisting) attempted to be registered!
Segmentation fault
  • 如果我注释 w.show(); 行,即使它进入主循环但没有显示窗口,程序也会编译并运行。
  • 如果我注释CXIndex index = clang_createIndex(0, 0);Q_UNUSED(index) 行,程序将编译并运行。它进入主循环,窗口可见。
  • 我也用 clang 编译了这个,我得到了同样的错误信息。
  • 我在网上搜索,只发现这个结果带有类似的错误消息,但我不知道它是否以及如何帮助我:http://comments.gmane.org/gmane.comp.compilers.llvm.devel/34647

我正在使用 Qt 5.1 和 ArchLinux,我安装了 clang 包(版本 3.3),其中包括 libclang 头文件和文件 /usr/lib/libclang.so 和 /usr/lib/libclang.a。

这个程序不工作的原因是什么,我该如何解决?


更新:我找到了this page。 运行LIBGL_ALWAYS_INDIRECT=1 ./test 效果很好,但我想要的不止这些。我不应该设置那个环境变量来运行我的程序。

【问题讨论】:

  • 尝试将 -lclang 放在 -lGL 之后。有时奇怪的链接器问题是由于顺序错误造成的。 Mesa 将 LLVM 用于着色器,因此这可能是您问题的根源
  • 这可能会有所帮助llvm.org/bugs/show_bug.cgi?id=6801
  • @Spudd86 我试过g++ -fPIE test.cpp -o test -I/usr/include/qt -I/usr/include/qt/QtWidgets -lGL -lQt5Widgets -lclang 并得到相同的运行时错误。
  • 在阅读了该错误报告后,我尝试链接我在 /usr/lib 目录中的一些 .a 文件,我认为这些文件是 clang 模块(如此处所示:clang.llvm.org/doxygen/dirs.html,在 clang 下/lib): libclangTooling.a、libclangAST.a、libclangFrontend.a 等。我在想,如果我只链接到我需要的 clang 模块,就不会有任何冲突。但是这些文件都没有clang_createIndex 函数,所以我得到了undefined reference to 'clang_createIndex' 错误。
  • LIBGL_ALWAYS_INDIRECT=1 无论如何都不是你想要设置的东西,你失去了对大部分 OpenGL 1.4 后的访问权限,因为它将你的 GL 命令发送到 X 服务器,并且没有低于古代 GL 的协议

标签: c++ qt clang libclang


【解决方案1】:

我可以回答你关于出了什么问题的部分问题,我不知道如何解决它。

首先,如果您没有 -Wl,--as-needed,删除 CXIndex index = clang_createIndex(0, 0); 不会解决问题,删除它只会修复它,因为链接器注意到您实际上并没有调用 libclang,因此实际上并没有链接您的程序没有CXIndex index = clang_createIndex(0, 0); 行。

出现问题的原因是因为您使用的任何 Mesa 后端(ATI 或 NVIDIA)也与 clang 链接。似乎正在发生的事情是,当您的程序首次加载并且动态链接解析时,链接器会加载 libclang 和其他 LLVM 内容 libclang 链接到并运行全局对象的构造函数,这就是 LLVM 自动注册它的内置传递的方式。因此,此时所有内置的 LLVM 通道都已注册,然后 QT 启动并创建一个 OpenGL 上下文,因此 Mesa 加载适当的 DRI 后端,并且在您的系统上发生后端使用 clang/LLVM 时,出于某种原因它似乎所有这些构造函数都再次运行,LLVM 注意到“两次”传递(实际上是相同的传递尝试注册自己两次)共享相同的名称并中止您的程序。

就像我说的,我真的不知道为什么构造函数会运行两次,也不知道如何让它停止。尝试在mesa-users 邮件列表中询问,如果您在那里没有得到答复,请尝试mesa-dev

Mesa 邮件列表:http://mesa3d.org/lists.html

编辑:您应该确保您的 Mesa 副本与您尝试使用的同一版本的 LLVM 链接,如果它没有修复通行证注册问题,那么您的问题将是最少的。

尝试ls /usr/lib64/llvm/libLLVM-?.?.so,如果你得到两件东西,你有两个版本的 libLLVM,这本身不是问题,但如果你链接一个版本,而 Mesa 链接到另一个版本,这可能会解释事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多