2013-07-30 12 views
6

Napotkałem dziwny błąd, gdy próbowałem użyć biblioteki libclang w aplikacji Qt.Nie można użyć libclang z Qt

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 

powłoki poleceń i wyjściowa:

$ 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 

przypadku ręcznie prowadzony g ++ bez użycia QMake, że pojawia się ten sam błąd:

  • Jeśli komentarz linię w.show(); program kompiluje się i działa nawet jeśli wejdzie ona główną pętlę bez oknie pokazanym na rysunku.
  • Jeśli skomentuję linie CXIndex index = clang_createIndex(0, 0); i Q_UNUSED(index), program skompiluje i uruchomi. Wchodzi do głównej pętli z widocznym oknem.
  • Również skompilowałem to z clang i otrzymuję ten sam komunikat o błędzie.
  • Przeszukałem Internet i znalazłem tylko ten wynik z podobnym komunikatem o błędzie, ale nie wiem, czy i jak może mi pomóc: http://comments.gmane.org/gmane.comp.compilers.llvm.devel/34647.

Używam Qt 5.1 i ArchLinux mam pakiet clang (wersja 3.3) zainstalowane który zawiera nagłówki libclang i pliki /usr/lib/libclang.so i /usr/lib/libclang.a.

Jaki jest powód, dla którego ten program nie działa i jak mogę go naprawić?


Aktualizacja: Znalazłem this page. Działa LIBGL_ALWAYS_INDIRECT=1 ./test działa dobrze, ale chcę więcej niż to. Nie powinienem ustawiać tej zmiennej środowiskowej, aby móc uruchomić mój program.

+0

Spróbuj wstawić -lclang po -lGL. Czasami dziwne problemy z linkerem wynikają z posiadania rzeczy w niewłaściwej kolejności. Mesa używa LLVM dla shaderów, więc może być źródłem twojego problemu. – Spudd86

+0

To może być pomocne http://llvm.org/bugs/show_bug.cgi?id=6801 – Spudd86

+0

@ Spudd86 Próbowałem 'g ++ -fPIE test.cpp -o test -I/usr/include/qt -I/usr/include/qt/QtWidgets -lGL -lQt5Widgets -lclang' i otrzymuję ten sam błąd środowiska wykonawczego. – silviubogan

Odpowiedz

2

Mogę odpowiedzieć na część pytania o to, co dzieje się nie tak, nie wiem jak to naprawić.

Po pierwsze, usunięcie CXIndex index = clang_createIndex(0, 0); nie naprawi rzeczy, jeśli nie masz -Wl,--as-needed usunięcie go naprawi tylko dlatego, że linker zauważył, że tak naprawdę nie zadzwoniłeś do biblioteki libclang, a więc nie włączyłeś do niego swojego programu bez linia CXIndex index = clang_createIndex(0, 0);.

Powód, dla którego złamanie jest spowodowane tym, że dowolne wsparcie dla Mesy (ATI lub NVIDIA) również łączy się z klangiem. Wygląda na to, że po pierwszym załadowaniu programu i rozwiązaniu linków dynamicznych linker jest uruchamiany i ładuje biblioteki libclang i inne pliki LLVM z biblioteki libclang i uruchamia konstruktory obiektów globalnych, tak jak LLVM automatycznie rejestruje wbudowane przejścia. W tym momencie wszystkie wbudowane przepustki LLVM są rejestrowane, a następnie uruchamiany jest QT i tworzy on kontekst OpenGL, więc Mesa ładuje odpowiedni backend DRI i jak to się dzieje w twoim systemie, backend używa clang/LLVM iz jakiegoś powodu to wydaje się, że wszystkie te konstruktory działają ponownie i LLVM zauważa, że ​​"dwa" podania (w rzeczywistości to samo przejście próbuje się zarejestrować dwa razy) mają tę samą nazwę i przerywają twój program.

Tak jak powiedziałem, tak naprawdę nie wiem, dlaczego konstruktorzy pracują dwa razy i nie wiem jak go zatrzymać. Spróbuj zapytać na liście dyskusyjnej mesa-users jeśli nie tam dostać odpowiedź spróbować mesa-dev

Mesa listach mailowych:

EDIT: Należy upewnić się, że dana kopia Mesa jest związany przeciwko tej samej wersji LLVM którego próbujesz użyć, jeśli to nie naprawi passy, ​​będzie to najmniejszy problem.

Spróbuj zrobić ls /usr/lib64/llvm/libLLVM-?.?.so, jeśli otrzymasz dwie rzeczy, masz dwie wersje biblioteki libLLVM, która nie stanowi problemu na własną rękę, ale jeśli łączysz jedną wersję i linki Mesa z inną wersją, która może wyjaśniać pewne rzeczy.