2013-07-30 36 views
6

當我嘗試在Qt應用程序中使用libclang時,遇到了一個奇怪的錯誤。不能在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的,我得到相同的錯誤:

  • 如果我評論的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效果不錯,但我想要的不僅僅是這個。我不應該設置該環境變量才能運行我的程序。

+0

嘗試把-lclang放在-lGL之後。有時奇怪的鏈接器問題是由於順序錯誤。 Mesa使用LLVM着色器,這可能是您的問題的根源 – Spudd86

+0

這可能會有所幫助http://llvm.org/bugs/show_bug.cgi?id=6801 – Spudd86

+0

@ Spudd86我試過'g ++ -fPIE test.cpp -o test -I/usr/include/qt -I/usr/include/qt/QtWidgets -lGL -lQt5Widgets -lclang',我得到相同的運行時錯誤。 – silviubogan

回答

2

我可以回答你的部分關於發生了什麼問題的問題,我不知道如何解決它。

首先,刪除CXIndex index = clang_createIndex(0, 0);不會修復的東西,如果你沒有-Wl,--as-needed刪除它只修復它,因爲鏈接器注意到你實際上沒有調用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

梅薩郵件列表:

編輯:你應該確保你的梅薩的副本對同一版本的LLVM的鏈接你試圖使用,如果它沒有解決通過註冊事情將是你的問題最少。

嘗試做ls /usr/lib64/llvm/libLLVM-?.?.so如果你有兩件事回來你有兩個版本的libLLVM,這本身並不是一個問題,但如果你鏈接到一個版本和Mesa鏈接對不同的版本,可能會解釋的東西。