LINUX.ORG.RU

Qt Creator - не могу добавить к проекту внутреннюю (Internal) библиотеку

 , ,


0

1

Имею Qt 5.9.2 и Qt Creator 4.4.1, Linux Debian 64 bit

Пытаюсь сделать все по вот этой статье: https://toster.ru/q/168437

Сделал основной проект в каталоге, например QGumboParserSampleSrc. В нем создал через git подкаталог lib, в котором лежит QGumboParser.pro, README.md и прочее.

В проекте *.pro прописал:

SUBDIRS += lib/QGumboParser

Далее нажимаю ПКМ на заголовке проекта, выбираю «Добавить библиотеку». Выбираю «Внутренняя», и мне открывается вот такое окно:

http://i.piccy.info/i9/8448938026d6329ecae1216192b41a8c/1513855996/64066/1202...

Поле «Библиотека» не разворачивается, оно может быть только пустым. Поле «Путь к заголовочным файлам» заполнял всеми возможным способами - указывал (через выбор директории) и lib, и lib/QGumboParser и lib/QGumboParser/gumbo-parser и lib/QGumboParser/gumbo-parser/src. Но какой каталог не указывай, поле «Библиотека» не заполняется, и видимо из-за этого не нажимается кнопка «Далее».

Я подумал, может нужны объектники, и запустил в каталоге lib
qmake QGumboParser.pro
make

Собралось без ошибок. Но после этого тоже ничего не поменялось: подключить библиотеку не могу.

Как ее вообще подключать?

★★★★★

Последнее исправление: Xintrea (всего исправлений: 1)

Ответ на: комментарий от UVV

Pro файл основного проекта? Он минимальный:

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

SUBDIRS += libs/QGumboParser

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Ну я так и думал. Короче смотри, qmake не может в multiple templates. Т.е. у тебя либо app, либо subdirs. Лечится это вот таким костылём:

TEMPLATE = subdirs
SUBDIRS = parser main

parser.subdir = libs/QGumboParser
main.subdir = app.pro
main.depends = parser

По синтаксису мог что-то напутать, вот здесь детальнее смотри https://wiki.qt.io/Undocumented_QMake

Либо вот так точно сработает

TEMPLATE = subdirs
SUBDIRS += libs/QGumboParser app.pro

но так зависимости надо где-то ещё прописать. Либо просто включаешь ordered и тоже должно быть норм.

UVV ★★★★★
()
Последнее исправление: UVV (всего исправлений: 1)
Ответ на: комментарий от UVV

Под app.pro что имеется в виду? Или так и нужно писать?

А после того как пропишу, в интерфейсе QtCreator нужно подключать библиотеку, или она уже будет считаться подключенной?

Xintrea ★★★★★
() автор топика
Последнее исправление: Xintrea (всего исправлений: 1)
Ответ на: комментарий от Xintrea

Под app.pro что имеется в виду?

Новый файл, в который ты перенесёшь вот это:

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += main.cpp

А после того как пропишу, в интерфейсе QtCreator нужно подключать библиотеку, или она уже будет считаться подключенной?

Без понятия. Я всегда правлю только pro-файлы. Я не знал, что нужно что-то ещё и в creator'e делать =)

UVV ★★★★★
()
Последнее исправление: UVV (всего исправлений: 1)
Ответ на: комментарий от UVV

То есть, получается, что невозможно просто так к основному проекту подключить библиотеку?

Нужно сделать «промежуточный» общий проект, к которому подключить и проект основной программы и проект библиотеки? Так чтоли?

А как тогда собирать? Нужно собирать промежуточный общий проект? Потому что проект основной программы не соберется?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Нужно сделать «промежуточный» общий проект, к которому подключить и проект основной программы и проект библиотеки? Так чтоли?

Если коротко, то да.

А как тогда собирать? Нужно собирать промежуточный общий проект? Потому что проект основной программы не соберется?

У тебя должен быть либо порядок сборки, либо зависимостями разрулить надо.

UVV ★★★★★
()
Ответ на: комментарий от Xintrea

Я в ТС статье не увидел pro файла. Там написано «открываем main.cpp», но нигде не написано, что он должен быть в pro-файле с template'ом subdirs.

UVV ★★★★★
()
Последнее исправление: UVV (всего исправлений: 1)
Ответ на: комментарий от UVV

Кстати, у меня каталог lib, а ты пишешь про libs, я не сразу это заметил. Я в ТС ошибся, и тоже написал SUBDIRS += libs/QGumboParser, но это в мом случае неправильно.

Компиляция в каком-то виде пошла, но почему-то не видны заголовочные файлы библиотеки:

../QGumboParserSampleSrc/main.cpp:6:28: fatal error: qgumbodocument.h: No such file or directory
 #include <qgumbodocument.h>

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от UVV

Вместо

#include <qgumbodocument.h>
#include <qgumbonode.h>


Указал вот так:

#include <./lib/QGumboParser/qgumbodocument.h>
#include <./lib/QGumboParser/qgumbonode.h>


Сборка пошла дальше, но застопорилась на ошибке:

main.o: In function `parseHtml(QString)':
/home/xi/work/develop/cpp/QGumboParserSample/build-QGumboParserSample-Desktop_Qt_5_9_2_GCC_64bit-Debug/../QGumboParserSampleSrc/main.cpp:45: undefined reference to `QGumboDocument::parse(QString const&)'
/home/xi/work/develop/cpp/QGumboParserSample/build-QGumboParserSample-Desktop_Qt_5_9_2_GCC_64bit-Debug/../QGumboParserSampleSrc/main.cpp:46: undefined reference to `QGumboDocument::rootNode() const'
/home/xi/work/develop/cpp/QGumboParserSample/build-QGumboParserSample-Desktop_Qt_5_9_2_GCC_64bit-Debug/../QGumboParserSampleSrc/main.cpp:48: undefined reference to `QGumboNode::getElementsByTagName(HtmlTag) const'
/home/xi/work/develop/cpp/QGumboParserSample/build-QGumboParserSample-Desktop_Qt_5_9_2_GCC_64bit-Debug/../QGumboParserSampleSrc/main.cpp:50: undefined reference to `QGumboNode::innerText() const'
/home/xi/work/develop/cpp/QGumboParserSample/build-QGumboParserSample-Desktop_Qt_5_9_2_GCC_64bit-Debug/../QGumboParserSampleSrc/main.cpp:45: undefined reference to `QGumboDocument::~QGumboDocument()'
Makefile.app:239: recipe for target 'app' failed
make[1]: Leaving directory '/home/xi/work/develop/cpp/QGumboParserSample/build-QGumboParserSample-Desktop_Qt_5_9_2_GCC_64bit-Debug'
Makefile:68: recipe for target 'sub-app-pro-make_first' failed
/home/xi/work/develop/cpp/QGumboParserSample/build-QGumboParserSample-Desktop_Qt_5_9_2_GCC_64bit-Debug/../QGumboParserSampleSrc/main.cpp:45: undefined reference to `QGumboDocument::~QGumboDocument()'
collect2: error: ld returned 1 exit status
make[1]: *** [app] Error 1
make: *** [sub-app-pro-make_first] Error 2

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от UVV

Последняя ошибка походу от того что при линковке не видятся объектники. Да как же их подключить

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от UVV

Что-то я не вкурю. Вот дока:

http://doc.qt.io/qt-5/qmake-variable-reference.html#libs

Там написано как подключать системные либы.

LIBS += -L/usr/local/lib -lmath


Насколько я понимаю, эта строка подключит либу
/usr/local/lib/libmath.so
или ее псевдонимы. Или ей подавай *.a? Фак, уже все забыл.

Про опцию -l в документации GCC говорится следующее:

-llibrary
-l library

    Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)

    It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded.

    The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.

    The directories searched include several standard system directories plus any that you specify with -L.

    Normally the files found this way are library files—archive files whose members are object files. The linker handles an archive file by scanning through it for members which define symbols that have so far been referenced but not defined. But if the file that is found is an ordinary object file, it is linked in the usual fashion. The only difference between using an -l option and specifying a file name is that -l surrounds library with ‘lib’ and ‘.a’ and searches several directories.


В моем случае библиотеки лежат в ./lib/QGumboParser, и имеют имена:

qgumboattribute.o
qgumbodocument.o
qgumbonode.o

Я задал опцию -L вот так:

LIBS += -L./lib/QGumboParser


Но либы все равно не видятся, то есть нужно видимо обязательно указывать еще и -l. Но эта опция требует чтобы имя начиналось с lib, и вроде расширение было .a?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Файл *.a нужен для статической линковки. Если линкуешься динамически, то *.so будет достаточно.

ox55ff ★★★★★
()
Ответ на: комментарий от Xintrea

LIBS += -L./lib/QGumboParser

Через -L задаёшь каталог, где искать. Через -l с чем линковаться.

ox55ff ★★★★★
()
Ответ на: комментарий от Xintrea

Смотри .pro проекта QGumboParser

CONFIG += staticlib c++11

Он собирается статически. В build директории будет файл libQGumboParser.a

В своём проекте в pro файле пишешь

INCLUDEPATH += ../lib/QGumboParser/QGumboParser
LIBS += ../lib/QGumboParser/QGumboParser/libQGumboParser.a
Всё слинкуется и будет работать. Я у себя проверил.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

Блин, я все время спотыкаюсь об этот LIBS. Вот в этой документации толком не написано, что можно просто либу указать:

http://doc.qt.io/qt-5/qmake-variable-reference.html#libs

Пишут про опции -L и -l для Linux, а для Windows примеров пишут напрямую просто файл либы.

Значит, для Linux можно писать не только -L и -l, но и просто файл либы писать?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Значит, для Linux можно писать не только -L и -l, но и просто файл либы писать?

LIBS это точно так же, как в обычных Makefile's:

Для динамической линковки libastral.so/libastral.dll: -L./путь_до_либы/ -lastral
Для статической линковки libastral.a: ./путь_до_либы/libastral.a

Справедливо и для MinGW. Для VSC++ компилятора немного по-другому.

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Ответ на: комментарий от Xintrea

но и просто файл либы писать?

Если нужна статическая линковка, то да, полный путь до файла .a

ox55ff ★★★★★
()
Ответ на: комментарий от Xintrea

То есть, в опции -L задается путь до каталога, в котором лежит файл библиотеки libastral.so/libastral.dll. А в опции -l задается имя библиотеки.

Про винду и компилятор msvc++ неправильно написал. Для линковки нужен файл с расширением lib, а не dll. Он генерируется при сборке динамической библиотеки. dll нужен во время работы приложения.

ox55ff ★★★★★
()
Ответ на: комментарий от EXL

Зачем собирать проект несвободным компилятором? Но если очень постараться, то можно

CC=cl.exe ./configure и т.д :D

Harald ★★★★★
()
Ответ на: комментарий от Harald

CC=cl.exe ./configure и т.д :D

Вот уж где реальный изврат.

ox55ff ★★★★★
()

Use QBS, luke :) и не будет проблем с зависимостями и прочим трешем.

kuzulis ★★
()
Ответ на: комментарий от Harald

Зачем собирать проект несвободным компилятором? Но если очень постараться, то можно

Компилятор свободно скачивается бесплатно и ставится на винду

UVV ★★★★★
()
Ответ на: комментарий от UVV

Вон биткоин-кошелёк с Qt-мордой таки автотулзами собирается. Популярнейший свободный программный проект, с 16 тысячами форков на гитхабе! Сатоши знал толк в правильных системах сборки!

Harald ★★★★★
()
Ответ на: комментарий от ox55ff

Про винду и компилятор msvc++ неправильно написал. Для линковки нужен файл с расширением lib, а не dll. Он генерируется при сборке динамической библиотеки. dll нужен во время работы приложения.

То есть, lib - это типа файла бинарных заголовков, чтобы потом dll могла динамически быть подключена?

А для статичекой линковки в Винде что используется?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

То есть, lib - это типа файла бинарных заголовков, чтобы потом dll могла динамически быть подключена?

Типа того. Функции, которые должны быть видны снаружи помечаются __declspec(dllexport). При создании dll будет создана библиотека импорта с расширением lib, в которой будет информация об экспортируемых символах dll. Это информация используется на стадии линковки.

А для статичекой линковки в Винде что используется?

Тоже файл lib, но более жирный. В настройках проекта указываешь, что это статическая библиотека и линкер засунет в файл lib объектные файлы obj.

Имеем следующую картину:
Win -> Linux
.obj -> .o
.lib -> .a

ox55ff ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.