Qt WinAPI - Урок 001. Как собрать все DLL, используемые в Qt-проекте?

WinAPI, DLL, DLL Collector, DLLCollector, Qt

Рано или поздно перед любым Qt-разработчиком встаёт необходимость переноса своего приложения на другие компьютеры, и тогда возникает проблема наличия библиотек на целевом компьютере, которые необходимы для запуска и работы приложения. Особенно заметно это может быть при переносе приложения, которое должно исполняться под ОС Windows. Если под ОС Linux необходимые Qt библиотеки могут присутствовать по умолчанию, как например с Ubuntu, то под ОС Windows их может и вовсе не быть.

Но поиск и сборка всех необходимых библиотек может оказаться трудной задачей для новичка, да и вполне нудной задачей для опытного программиста. Но и здесь благодаря добрым людям имеется решение. Это утилита DLL Collector. Данная утилита позволяет получить зависимости программы, которая была написана на фреймворке Qt и автоматически скопировать данные библиотеки в заданную папку.

Как пишет Автор , утилита производит поиск зависимостей в runtime процесса. Следовательно Вашу программу необходимо запустить через данную утилиту. DLL Collector собирает информацию о всех подгружаемых Плагинах, используемых Вашей программой, но при этом не стоит забывать, что плагины подгружаются при первом использовании их функциями Вашей программы. Таким образом, необходимо сделать прогон Вашей программы по её функционалу, чтобы DLL Collector нашёл все библиотеки.

Как работает DLL Collector

Шаг первый. Настройка утилиты

На данном шаге необходимо произвести следующие действия:

  1. Указать в поле name путь к скомпилированной программе;
  2. Указать в поле bin путь к бинарным файлам библиотек Qt;
  3. Указать в поле plugins путь к  плагинам Qt;
  4. Указать путь к папке, куда будут скопированы DLL библиотеки
  5. Поставить галочку напротив add bin to envitonment

Шаг второй. Запуск Вашего приложения

После того, как настройка произведена, запускаем Ваше приложение нажатием кнопки Run.

Шаг третий. Обновление списка плагинов и библиотек

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

Шаг четвертый. Копирование библиотек

После того, как библиотеки найдены, нажмите кнопку Copy, и все библиотеки будут скопированы.

Резюме

Подводя итоги, могу утверждать, что утилита весьма полезна и значительно облегчает жизнь.

На момент написания статьи Автор выложил новую версию программы, но лично у меня она крашилась. Поэтому я до сих пор пользуюсь более старой версией, которую вы можете скачать здесь: DLLCollector

Также Вы можете ознакомиться с программой на странице Автора.

Также не забудьте сделать инсталлятор для своего приложения, а как это делается узнайте в следующей статье .

Видеоурок

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
Поддержать автора Donate
V

Старой или последней версией пользуетесь? В статье по ссылке есть более старая версия. Она работала лучше, чем последняя версия. К сожалению, не могу проверить работоспособность утилиты, поскольку не имею ни одной установки Windows на данный момент.

Также можете ещё посмотреть в сторону официальной утилиты от Qt. Вот ссылка.
V

Старая не работает с компиляторами msvc , попросту ничерта не находит , новая с ними же выдаёт ошибку при нажатии updаte , обе версии работают  с mingw , однако старая нашла 51 модуль , новая 45. И обе игнорят целый пакет библиотек от MS VS . В общем , подскажите аналогичную программу , может тогда всё нормально станет.

Есть ещё Dependency Walker. Сам не использовал, но часто натыкался на форумах, что его советуют для поиска DLL-ок.

Вероятно по тому что Вы пытаетесь использовать сборщик x32 для сборки Qt x64.
Стоило скачать исходники сборщика и перекомпилить.

Dependency Walker не справляет с этой задачей он не видит плагинов.

Если использовать, то использовать ProcessExplorer которыей в принципе должен отображать то же что и мои сборщик.

Кстати программу я давно обновил, если есть замечания по работе пишите в мой лучше в блог.

Добрый день!

А почему вы не предоставляете сборку программы и для x64?
Я как бы понимаю, что программисту не должно составить труда перекомпилить программу из исходников. Но плюс вашей софтины в том, что она удобна для новичков. А опытный Qt-программист скорее будет использовать windeployqt.
То есть не каждый новичок сразу разберётся с компиляцией сборщика из исходников под необходимую целевую платформу.
Так что, возможно имело бы смысл сделать несколько сборок под последние актуальные версии MSVC.
Или у вас есть некоторые дополнительные аргументы против?

Добрый день!
У меня нет возможности собрать под x32.

Кроме того если человек до сих по не научился нажимать кнопочку "собрать" проект, то ему лучше вообще не заниматься программированием.

И почему только для новичков?
Профи программистами не нужно собирать ддлки в кучу?

Касательно windeployqt:
1. Cобирает не все.
2. Cобирает то что вообще не нужно, порой такое впечатление что он тупо копирует все подряд.
3. Ну и как понимаю он не анализирует зависимости от сторонних библиотек.





Поправка: У меня нет возможности собрать под x64.

Да и я еще планирую поддерживать сборку под Linux.
Но по в связи с внесением изменений она не работает.

К сожалению, ваша программа работает только в рантайме,

  1. Запустить Вашу программу из QtCreator.
  2. Прогнать Вашу программу по всему функционалу , что бы она подгрузила все плагины и qml библиотеки.
Конечно, она позволяет проанализировать все зависимости и взять только необходимое, но при этом нужно запускать программу и прогонять её вручную по функционалу.

Но вы понимаете, что в некоторых случаях и некотором рабочем процессе внедрять подобное не имеет смысла.
Я например работаю над проектом, билд которого разворачивается на пару десятков гигабайт, а сборка билдов для тестирования осуществляется через Service Jenkins в автоматическом режиме. Как бы в крупных проектах многое стараются автоматизировать, поэтому возьмут windeployqt и никого не будет волновать наличие пары десятков лишних библиотек занимающих 50 мб, когда исходный комплект со всеми библиотеками весит 2 Гб.
А сторонние либы идут предкомпилированные в репозитории и собираются через qmake в общий билд.

Прогонять такую софтину по всему функционалу в одних только автоматических тестах составляет несколько часов. А вручную задача непосильная.

В общем со всех сторон есть вполне адекватные доводы, и я согласен с вашими насчёт windeployqt. Но тут уже вопрос компромиса.

А так меня интересовало вообще про x64, но если нет возможности, то тогда вопросов не имею. Спасибо.

Моя программа работает в рантайме ибо нет другого способа узнать все зависимости.

Как что от чего зависит внутри Qt могут знать только разработчики Qt.
Но то что windeployqt работает криво говорит от том что и у них проблемы с пониманием.

Я уже не говорю о той фигне которую они придумали в последних версиях (вшитых хардкор путях).


Как бы в крупных проектах многое стараются автоматизировать, поэтому возьмут windeployqt и никого не будет волновать наличие пары десятков лишних библиотек занимающих 50 мб, когда исходный комплект со всеми библиотеками весит 2 Гб.
Ну с таким успехом можно тупо копирнуть папку QtDIR
И удалить все лишнее.

Получите где-то ~200 MБ это как и будет весь Qt комплект (а не 50M или 2ГБ)






А насколько часто Вы собираете деплой?
Это как бы делается в самом конце так что не должно быть частым.

Деплой делается при каждом коммите, каждой ветви, автоматически, чтобы тестировщики могли проводить тестирование проекта нон-стоп.

На проекте работает 60+ программистов, каждый работает в среднем над одной двумя User Story, плюс каждый багфикс делается в отдельной ветви.
И каждая ветвь билдится. Тестировщик просто скачивает готовый чистый билд со всеми библиотеками.
Под сборку выделен отдельный сервер. Помимо Qt используем Open Cascade, Wt::dbo, Boost и ещё ряд библиотек, так что Qt занимает лишь малую часть. Поэтому на выходе имеем 700 мб.
Так что... примерно 50-60 деплоев в день будет. Если не больше.

Согласен, это морока.
Качать каждый раз по 700M ...

Сомневаюсь что сам набор библиотек так часто меняться по крайней мере касающихся Qt

Да, набор библиотек часто не меняется, но отслеживать в рантайме... это не имеет смысла, проще раз написать скрипт, который будет собирать всё, что нужно и немного лишнего, но зато всё будет работать. Так и живём )) Поэтому и говорю, что пару лишних либ из Qt никто даже не заметит ))

Но ваша софтина замечательна для небольших проектов и при первом деплое, когда вообще непонятно, какой библиотеки не хватает и откуда её брать. Очень удобно.

Если будет время, я сделаю билд под x64 на работе. Я напишу, когда будет готово.

Это вообще лишено смысла, пусть тестировщик держит все либы у себя на компе, и подменяет только исполняемый файл. А деплоить только перед финальным выпуском.

Сам проект состоит примерно из 20-ти подпроектов и все билдится в библиотеки. Запускаемый файл весит 28кб, а собираемые библиотеки, которые были написаны в рамках проекта - остальные 300 мб.
Если бы всё собиралось в один исполняемый файл, то программисты бы очешуели ждать пересборку при каждом изменении кода.

Используем специальный python-скрипт, который склеивает исходники перед сборкой, поэтому полный чистый билд составляет 27 минут, без скрипта 3 часа ))))
Так что просто заменить исполняемый файл не канает

Ну сути это не меняет.

Нет смысла деплоить одно и тоже каждый раз.

Какая-то библиотека может быть изменена в рамках одной единственной ветви из более чем 200 веток, над которыми работают в текщий момент времени.
Предлагаете обучать каждого тестировщика отслеживать, изменилась ли какая-то из библиотек? Бред. Люди имеют свойство забывать и ошибаться. Автоматический скрипт подготовит все необходимые библиотеки и уложит в подготовленный полноценный пакет. Тестировщику нужно лишь знать, откуда скачать.

Библиотека Qt ?

Qt тоже. Там тоже хватает багов, которые мы исправляем.

Про главным образом Qt и шла речь,
Если правятся исходники Qt то согласен для этого случая иначе нельзя.

А при чём тут только один Qt? Ваша же программа собирает и другие зависимые библиотеки. А значит здесь не только Qt, помимо прочего я уже говорил про Wt::dbo, Boost, Open Casecade. Может быть User Story на обновление библиотеки или исправление какого-то бага в этой библиотеки. Зачем заниматься ручной работой и напоминать тестировщику, что если программист что-то исправил, то нужно заменить библиотеку? Есть для этого автоматический скрипт, который просто потратит немного процессорного времени на копирование. Этого гораздо менее накладно, чем нагружать людей лишней ручной работой.

По тому что LibraryCollector заточен конкретно именно под деплой Qt приложений.
Он видит другие зависимости но не делает из сборку
(да и откуда программе знать что нужно для Вашего специфичного проекта)

Пользователь должен сам найти в списке нужные библиотеки и чекнуть их что бы они скопировались(при чем будет тупое копирование в папку исп.файла).

В новой версии LibraryCollector можно добавить свои правила правкой js-скрипта что бы настроить сборку согласно специфике своего проекта и его библиотек.
(Например, если у Вас такая же муторная система плагинами с иерархией папок)



Или Вы хотите сказать что windeployqt видит зависимости от

Wt::dbo, Boost, Open Casecade.
?

Нет, это я не хотел сказать (к сожалению это не так). Говорю о том, что Ваша программа отлично справляется со своей функцией и позволяет также найти недостающие сторонние библиотеки, но это может быть только разовая операция, чтобы разобраться с конкретной проблемой (ну не получается найти конкретную нужную версию (будем считать, что разработчик жёстко не выспался сегодня)), но в рамках автоматизации сборку Qt библиотек лучше положить на windeployqt, если только у вас не поддерживается консольный вариант работы (?), а сторонние бибилотеки держать в рамках репозитория и производить их копирование в итоговый билд. Чтобы просто не нагружать специалистов не нужной работой, а всю сборку просто поставить на поток через автоматизацию.

Но опять же... у вас зависимости ищутся в рантайме. Что также не получится автоматизировать... к сожалению...

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

В таких случаях достаточно проанализировать структуру PE файла (экзешника)
а точнее таблицу импорта (даже не нужно запускать процесс)

Вся проблема в плагинах Qt которые отслеживаются только в процессе и только после прогона по функционалу. Могу конечно предположить что есть библиотеки которые делают так же, но не могу привести примеры.

Консольный вариант можно легко допилить, но смысла мало ибо по любому нужен прогон программы по функционалу.
 

Кстати так советуемый на форумах Dependency Walker скорее всего так и делает- анализирует таблицу импорта - и видит только модули Qt, а плагины и qml пропускает.


Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Как стать автором?

Внесите вклад в развитие сообщества EVILEG.

Узнайте, как стать автором сайта.

Изучить
Donate

Добрый день, Дорогие Пользователи !!!

Я Евгений Легоцкой, разработчик EVILEG. И это мой хобби-проект, который помогает учиться программированию другим программистам и разработчикам

Если сайт помог вам, и вы хотите также поддержать развитие сайта, то вы можете сделать пожертвование следующими способами

PayPalYandex.Money
Timeweb

Позвольте мне порекомендовать вам отличный хостинг, на котором расположен EVILEG.

В течение многих лет Timeweb доказывает свою стабильность.

Для проектов на Django рекомендую VDS хостинг

Посмотреть Хостинг Timeweb
5 июня 2020 г. 23:20
Алексей

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:60баллов,
  • Очки рейтинга-1
5 июня 2020 г. 23:15
Алексей

C++ - Тест 001. Первая программа и типы данных

  • Результат:53баллов,
  • Очки рейтинга-4
V
5 июня 2020 г. 16:47
Vladzo

C++ - Тест 005. Структуры и Классы

  • Результат:83баллов,
  • Очки рейтинга4
Последние комментарии
6 июня 2020 г. 15:13
Владислав Меленчук

Как установить и настроить Django JET

Можно использовать six и оттуда импортировать unicode. Я так решил проблему) Но всё равно откатился обратно на админку джанги.
6 июня 2020 г. 11:20
BL4CK R4BBIT

Как установить и настроить Django JET

на Django >3+ работать не будет. Либо придется лезть внутрь и переопределять метод unicode . Либо писать декоратор
5 июня 2020 г. 10:52
progammist

Распознавание изображений на Python с помощью TensorFlow и Keras

Огромное спасибо за метериал, по-больше бы подобных статей (с подробным описанием работы и примерами применения) на тему современных технологий. Вопрос поразмышлять. На текущий момент реал…
5 июня 2020 г. 1:39
Евгений Легоцкой

Qt/C++ - Урок 091. Как написать кастомный делегат управляющий подсветкой строки в таблице

По-моему, смысла в этом нет особого. Если делегат будет игнорировать настройки таблицы, то это приведёт ещё к большему непониманию, что вообще происходит, для программиста, который после вас буд…
5 июня 2020 г. 1:34
IscanderChe

Qt/C++ - Урок 091. Как написать кастомный делегат управляющий подсветкой строки в таблице

Сижу, размышляю: можно ли переписать делегата так, чтобы независимо от настроек строк выделялись строки?
Сейчас обсуждают на форуме
u
6 июня 2020 г. 7:26
ubomj

Галерея изображений

delete
s
6 июня 2020 г. 1:54
shuric

Qt/C++ Определение положения курсора над действие(кнопкой) в QToolBar

Доброго дня. Возник вопрос - как можно определить что курсор находится над определенным действием(кнопкой) в qtoolbar ? mainwindow.cpp MainWindow::MainWi…
s
6 июня 2020 г. 0:45
shuric

Qt/C++ особенности QProxyStyle

Да, Вы правы. Код был скопирован с сайта (уже не помню с какого), но решил пойти по пути более легком. Пришлось переписать - кому интересно: использовал stackedWidget для пе…
5 июня 2020 г. 23:08
Алексей

Посоветуйте новичку (базы данных и Qt, что учить)

Блин, а я недавно купил Шлее Qt 5.10 :( С детства хотел стать программистом, баловался Паскалем, писал простенькие программки на Delphi, создавал движок на php, изучал C (забросил и перешел на п…
5 июня 2020 г. 13:09
IscanderChe

QPlainTextEdit настройка цвета фона

Вечер добрый. Пытаюсь настроить цвет фона QPlainTextEdit следующим образом: CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent){ ... QPalette::ColorRole role = bac…
О нас
Услуги
© EVILEG 2015-2020
Рекомендует хостинг TIMEWEB