Не могу использовать libclang с Qt

Я столкнулся со странной ошибкой, когда пытался использовать libclang в приложении 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

Команды оболочки и вывод:

$ 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

Если я вручную запускаю g ++ без использования qmake, я получаю ту же ошибку:

$ 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(); line программа компилируется и запускается, даже если она входит в основной цикл без показанного окна.
  • Если я прокомментирую 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.

По какой причине эта программа не работает и как я могу это исправить?


Обновить: я обнаружил эта страница.
Бег LIBGL_ALWAYS_INDIRECT=1 ./test работает хорошо, но я хочу больше, чем это. Мне не нужно было устанавливать эту переменную окружения, чтобы иметь возможность запускать мою программу.

6

Решение

Я могу ответить на ваш вопрос о том, что идет не так, я не знаю, как это исправить.

Во-первых, удаление CXIndex index = clang_createIndex(0, 0); не исправить вещи, если бы у вас не было -Wl,--as-needed его удаление исправляет только потому, что компоновщик заметил, что вы на самом деле не вызывали libclang, и поэтому не связывали вашу программу с ним без CXIndex index = clang_createIndex(0, 0); линия.

Причина этого заключается в том, что любой используемый в Mesa бэкэнд (ATI или NVIDIA) также связывается с клангом. Кажется, что происходит то, что когда ваша программа загружается впервые и динамические ссылки разрешаются, компоновщик запускает и загружает 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 ссылается на другую версию, которая может что-то объяснить.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]