Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use libclang with Qt

I encountered a strange bug when I tried to use libclang in a Qt application.

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 commands and output:

$ 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

If I manually run g++ without using qmake, I get the same error:

$ 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
  • If I comment the w.show(); line the program compiles and runs even if it enters the main loop without the window shown.
  • If I comment the CXIndex index = clang_createIndex(0, 0); and Q_UNUSED(index) lines, the program compiles and runs. It enters the main loop with the window visible.
  • I also compiled this with clang and I get the same error message.
  • I searched the web and I found only this result with a similar error message but I don't know if and how it can help me: http://comments.gmane.org/gmane.comp.compilers.llvm.devel/34647 .

I am using Qt 5.1 and ArchLinux, I have the clang package (version 3.3) installed which includes the libclang headers and the files /usr/lib/libclang.so and /usr/lib/libclang.a.

What is the reason why this program does not work and how can I fix it?


Update: I've found this page. Running LIBGL_ALWAYS_INDIRECT=1 ./test works well, but I want more than this. I shouldn't have to set that environment variable to be able to run my program.

like image 832
silviubogan Avatar asked Jul 30 '13 17:07

silviubogan


1 Answers

I can answer the part of you question about what's going wrong, I don't know how to fix it.

First, removing the CXIndex index = clang_createIndex(0, 0); wouldn't fix things if you didn't have -Wl,--as-needed removing it only fixes it because the linker noticed you didn't actually call into libclang and so didn't actually link your program to it without the CXIndex index = clang_createIndex(0, 0); line.

The reason things a breaking is because whatever Mesa backend you are using (either ATI or NVIDIA) also links against clang. What seems to be happening is that when your program is first loaded and dynamic links resolved the linker goes and loads libclang and other LLVM stuff libclang links to and runs the constructors for global objects, which is how LLVM registers it's built in passes automatically. So at this point all of the built in LLVM passes are registered, then QT starts up and it creates an OpenGL context so Mesa loads the appropriate DRI backend and as it happens on your system that backend uses clang/LLVM, and for some reason it seems that all those constructors run again and LLVM notices that "two" passes (actually the same pass trying to register itself twice) share the same name and aborts your program.

Like I said I don't really know why the constructors are running twice and I don't know how to make it stop. Try asking on the mesa-users mailing list if you don't get an answer there try mesa-dev

Mesa mailing lists: http://mesa3d.org/lists.html

EDIT: You should make sure that your copy of Mesa is linked against the same version of LLVM that you are trying to use, if it's not fixing the pass registration thing will be the least of your problems.

Try doing ls /usr/lib64/llvm/libLLVM-?.?.so if you get two things back you have two versions of libLLVM which is not a problem on it's own, but if you're linking against one version and Mesa links against a different version that might explain things.

like image 147
Spudd86 Avatar answered Oct 02 '22 00:10

Spudd86