Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Кроссплатформенный C/C++: cl/gcc/Qt/Gtk+/WxWidgets > Подключение библиотеки GMP к Qt-проекту


Автор: jml 08.12.19, 06:36
Привет привет!

Нужна помощь в настройке импорта GMP библиотеки.
Сама библиотека скомпилировалась без проблем с первого раза.
Архив с бинарниками и хидер тут: https://www.sendspace.com/file/64itww

В Qt используя MinGW делаю тестовое консольное C-приложение.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // main.c
    #include <stdio.h>
    #include "../_GMP_/gmp-6.1.2/include/gmp.h"
     
    int main()
    {
    mpz_t x;
     
        mpz_init_set_si(x, 1);
     
    return(0);
    }

Настройки pro файла проекта
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    TEMPLATE = app
    CONFIG += console
    CONFIG -= app_bundle
    CONFIG -= qt
     
    SOURCES += \
            main.c
     
    win32: LIBS += -L$$PWD/../_GMP_/gmp-6.1.2/lib/ -llibgmp.dll
     
    INCLUDEPATH += $$PWD/../_GMP_/gmp-6.1.2/include
    DEPENDPATH += $$PWD/../_GMP_/gmp-6.1.2/include

Все нужные файлы на своих местах.
Но. При компиляции получаю это
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    C:\Qt\Projects\TestGMP\main.c:-1: ошибка: undefined reference to `_imp____gmpz_init_set_si'
    collect2.exe:-1: ошибка: error: ld returned 1 exit status


Проблемная функция (а они сейчас все такие), определена в gmp.h как
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #define mpz_init_set_si __gmpz_init_set_si
    __GMP_DECLSPEC void mpz_init_set_si (mpz_ptr, signed long int);

То есть судя по тексту ошибки, макрос __GMP_DECLSPEC добавляет префикс _imp_ к имени функции (в библиотеке таких имен конечно нет) и я не знаю правильно ли это.
Примеры которые удалось найти в интернетах так и не смогли помочь понять проблему.
ЧЯДНТ??

Автор: JoeUser 08.12.19, 08:05
Прочитай внимательно доку - https://doc.qt.io/qt-5/third-party-libraries.html
И обрати дополнительно внимание на раздел "Library Files" - это, видать, твой случай. Обрати внимание на терминальные слэши в путях, кавычки для путей, в общем детали ... Я имею ввиду в файле проекта. Линкер недоволен.

Автор: jml 08.12.19, 12:05
JoeUser
Прочитал ещё раз. Ничего нового для себя не узнал. Пробелов в путях нет. Кавычек тоже.

Как вообще можно получить такую ошибку при статической линковке длл-ки?

Автор: JoeUser 08.12.19, 12:56
jml, ну вот сравни что в доке (пример):
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    TARGET = MyQtApp
    TEMPLATE = app
    INCLUDEPATH += 3rdparty/CatWhisperer/include
    SOURCES += src/main.cpp
    LIBS += -L"3rdparty/CatWhisperer/lib" -lCatWhisperer

Вот тут у аргумент LIBS заключен в двойные кавычки, у тебя - нет.
Там же путь без завершающего слеша, у тебя со слешем.
Попробуй заключить в кавычки и убрать завершающий слеш.

И тут еще глянь. Может либа как-то иначе именуется, например с цифрами.

Автор: jml 08.12.19, 13:27
JoeUser
По той же ссылке про кавычки.
Цитата
The double quotes are only necessary when the path contains spaces, so we could have omitted them in this example.

Последний слеш тоже пробовал убирать. Без изменений.
Но былобы смешно еслиб влияло. Неужели разрабы Qt не додумались проверить последний слеш при конкатенации имен путей/файлов.

А вот полностью убрал строку "LIBS += " и .. ничего не изменилось, та же ошибка.
Т.е. он не видит библу libgmp.dll.a ?
А если библу видит а функцию найти не может, вывод оибки был бы тот же?

Автор: jml 08.12.19, 15:11
https://forum.qt.io/topic/40855/undefined-r...r-is-included/4
Цитата
MinGW also uses .a library files on the Windows platform, but that does not mean you can use Linux .a files on Windows with MinGW. You can't! ;-)

Похоже чел прав. Нельзя вот просто так взять и использовать статическую библу Линуха на Вин. Не просто нельзя в MSVS а вообще на Windows нельзя.

Надо делать *.lib файл из *.a.
А для этого обязательно надо ставить MSVS или в Qt/MinGW есть готовые инструменты?

Автор: JoeUser 08.12.19, 15:40
Цитата jml @
А для этого обязательно надо ставить MSVS или в Qt/MinGW есть готовые инструменты?

:lol: Прям щя сам под Manjaro собираю MXE (http://mxe.cc)

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #!/bin/sh
    git clone https://github.com/mxe/mxe.git
    cd mxe
    make MXE_TARGETS='i686-w64-mingw32.shared i686-w64-mingw32.static x86_64-w64-mingw32.static x86_64-w64-mingw32.shared i686-w64-mingw32.shared.posix i686-w64-mingw32.static.posix x86_64-w64-mingw32.static.posix x86_64-w64-mingw32.shared.posix' postgresql libmysqlclient sqlite xz -j2 JOBS=2
    make MXE_TARGETS='i686-w64-mingw32.shared i686-w64-mingw32.static x86_64-w64-mingw32.static x86_64-w64-mingw32.shared i686-w64-mingw32.shared.posix i686-w64-mingw32.static.posix x86_64-w64-mingw32.static.posix x86_64-w64-mingw32.shared.posix' luajit qt5 -j2 JOBS=2

Там и тебе нужная либа есть, если не ошибаюсь, ставится по-умолчанию.
Вру, ставится только хостовая версия, а для кросс-компиляции нужно в make ее аргументом указывать.

Автор: jml 08.12.19, 17:26
JoeUser не представляю чем это этот микс может мне помочь сейчас.
мне просто нужно прицепить статически дллку к проекту. всё.

Вобщем сделал libgmp.lib посредством dlltool.exe из MinGW. Добавил в проект И ничо не изменилось :wall:
Больше идей пока нет
:whistle:

Автор: JoeUser 08.12.19, 18:08
Цитата jml @
JoeUser не представляю чем это этот микс может мне помочь сейчас.

Ну у меня эти 6 комплектов будут до утра собираться. Завтра уже попробую с нужной тебе либой поэксперементировать.

Добавлено
Цитата jml @
dlltool.exe

И да ... я Qt+Mingw давно под вендой не пользовал, исключительно под Линухом и кросскомпиляторами из MXE.

Автор: jml 09.12.19, 02:14
JoeUser
"Дело было не в бобине.."

Решил проверить какой экзешник получится если собрать без длл-ки вообще. Посмотрел потом его хидер, а там
Цитата

OPTIONAL HEADER :
Magic 010Bh ( PE32 : normal 32-bit )
Linker version 2.30

Т.е. по сути, я всё это время пытался склеить 32-разрядный экзешник с 64-битной длл-кой.
Создал новый проект с комплектом MinGWx64 и всё собралось(с дллкой) без бубнов с первого раза.

Ещё по теме:
1. *.lib файл всё таки не нужен MinGW даже в Вин. Достаточно *.a файла.
2. ПКМ на имени проекта - "Добавить библиотеку..." и вызывается мастер добавления библиотеки в проект. Так меньше шансов ошибиться в записях *.pro файла проекта.
3. Правильное название GMP длл-ки, всё таки - libgmp-10.dll

Спасибо за участие JoeUser :victory:

Автор: JoeUser 09.12.19, 05:02
Молоток! :good:

Добавлено
Цитата JoeUser @
3. Правильное название GMP длл-ки, всё таки - libgmp-10.dll

Цитата JoeUser @
Может либа как-то иначе именуется, например с цифрами.

Да, в MinGW (вернее в тулчейнах GCC) - это распространенное явление.

Автор: JoeUser 09.12.19, 12:25
Выбрал время, провел тест после развертывания MXE, и вот что получилось:

Либу GMP развернул стандартным способом во все туллчейны:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    cd mxe
    make MXE_TARGETS='i686-w64-mingw32.shared i686-w64-mingw32.static x86_64-w64-mingw32.static x86_64-w64-mingw32.shared i686-w64-mingw32.shared.posix i686-w64-mingw32.static.posix x86_64-w64-mingw32.static.posix x86_64-w64-mingw32.shared.posix' gmp -j2 JOBS=2

конфиг проекта проги (добавлял либу из QtCreator'a, руками ничё не правил):

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    TEMPLATE = app
    CONFIG += console
    CONFIG -= app_bundle
    CONFIG -= qt
     
    SOURCES += \
                    main.c
     
    win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../cross/mxe/usr/x86_64-w64-mingw32.shared.posix/lib/ -llibgmp.dll
    else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../cross/mxe/usr/x86_64-w64-mingw32.shared.posix/lib/ -llibgmp.dlld
     
    INCLUDEPATH += $$PWD/../../cross/mxe/usr/x86_64-w64-mingw32.shared.posix/include
    DEPENDPATH += $$PWD/../../cross/mxe/usr/x86_64-w64-mingw32.shared.posix/include

код прежний, единственное что - заголовки у меня в тулчейнах прописаны заранее, поэтому никаких путей в инклюдах писать не нужно:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <stdio.h>
    #include <gmp.h>
     
    int main()
    {
      mpz_t x;
      mpz_init_set_si(x, 1);
      printf("Hello World!\n");
      return 0;
    }

Деплой получился таков:

libgmp-10.dll (714193 байта)
TestGMP.exe (17480 байта)

Потом вспомнил, что в туллчейнах я не пострипал *.exe и *.dll, вот после стрипа:

libgmp-10.dll (443392 байта)
TestGMP.exe (17480 байта)

Кстати ... скрипт для стрипа всех туллчейнов набора MXE, вдруг пригодится:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #!/bin/sh
     
    # enter your path:
     
    export MXE=/home/majestio/Dev/cross/mxe/usr
     
    Strip () {
      find $MXE/$1 -iname '*.exe' -exec chmod 1755 {} \;
      find $MXE/$1 -iname '*.dll' -exec chmod 1755 {} \;
      find $MXE/$1 -iname '*.exe' -exec $MXE/bin/$1-strip {} \;
      find $MXE/$1 -iname '*.dll' -exec $MXE/bin/$1-strip {} \;
    }
     
    # Invoke your function:
     
    Strip "i686-w64-mingw32.static"
    Strip "i686-w64-mingw32.static.posix"
    Strip "i686-w64-mingw32.shared"
    Strip "i686-w64-mingw32.shared.posix"
    Strip "x86_64-w64-mingw32.static"
    Strip "x86_64-w64-mingw32.static.posix"
    Strip "x86_64-w64-mingw32.shared"
    Strip "x86_64-w64-mingw32.shared.posix"

Резюме

Плюс такого подхода - никогда не будет путаницы версий исполняемых модулей и нужных им библиотек.

Автор: jml 10.12.19, 01:13
И у тебя получилось 8 версий либы GMP. Круто)
Кросскомпиляцией интересовался постольку поскольку. Обычно, для Винды компилю в Винде, для Линуха в Линухе.
Я тут подумал, если эти миксы так хороши, замути сервис - озолотишься.

Автор: JoeUser 10.12.19, 06:04
Цитата jml @
И у тебя получилось 8 версий либы GMP. Круто)

Вообще-то - четыре, так как остальные четыре сборки статические.
Там либа линкуется статически в исполняемый модуль :)

Автор: jml 10.12.19, 11:16
Цитата JoeUser @
либа линкуется статически в исполняемый модуль

Это конечно так. Просто я был так поражен результатом что потерял им счёт.
Главное, мы друг друга поняли :)

Автор: JoeUser 10.12.19, 16:11
:victory:

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)