Форум программистов, компьютерный форум, киберфорум
Avazart
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
Темы блога относятся к программированию на языке С++

В основном для C++Qt (Qt5.1) и C++ Builder (RAD 2009 и RAD XE3)

LibraryCollector - программа для сборки библиотек для переноса Qt-приложений

Запись от Avazart размещена 15.06.2014 в 15:13
Показов 147019 Комментарии 1

Нажмите на изображение для увеличения
Название: LC_js.jpg
Просмотров: 2812
Размер:	178.6 Кб
ID:	4690

Содержание

1. Предназначение.
2. Как пользоваться LibraryCollector?
3. Теория или принципы работы LibraryCollector.
3. Настройка QtCreator для запуска LibraryCollector как внешней утилиты.
4. Js -сценарий
5. Ссылки.Блоги.Темы.Исходники.


1. Предназначение.

Программа LibraryCollector предназначена для получения списка зависимостей.
Под зависимостями имеются ввиду динамические библиотеки *.dll/*.so модули и плагины Qt используемые программой. LibraryCollector позволяет выполнить автоматическое копирование этих зависимостей/библиотек в указанную папку для последующего переноса программы на другой компьютер где не установлен Qt или последующего создания из них инсталятора. При копировании LibraryCollector учитывает иерархию папок расположения плагинов Qt.

В принципе LibraryCollector это моя альтернатива windeployqt и CQtDeployer с тем отличием что сборка идет на основе анализа библиотек(модулей) уже запущенного процесса собираемой программы на машине на которой есть Qt (запущенной из QtCreator).




2. Как пользоваться LibraryCollector?
  1. Запустить Вашу программу из QtCreator.
  2. Прогнать Вашу программу по всему функционалу, что бы она подгрузила все плагины и qml библиотеки.
  3. Запустить LibraryCollector.
  4. Указать полный путь к исполняемому файлу Вашей программы (в LibraryCollector). Это можно сделать с помощью кнопки "+" указав курсором на окно Вашей программы.
  5. Указать путь к QTDIR - путь где расположена сама библиотека Qt (в ней расположены папки bin, plugins, qml идр)
  6. Указать в поле ввода "to" куда будут собираться все библиотеки и копироваться исполняемый файл.
    По умолчанию все копирует в папку с исполняемым файлом.
    В этом поле с помощью регулярных выражений автоматически подменяются:
    • <ExeDir> - на путь к папке где лежит исполняемый файл программы
    • <BaseName> - на имя исполняемого файла без расширения.

  7. Нажать кнопку "Update" - в окне LibraryCollector отобразятся все подгруженные Вашей программой библиотеки разбитые по группам.Стандартные библиотеки будут отмечены галочкой.Если Вы используете свои библиотеки или библиотеки сторонних разработчиков Вы должны их выбрать в окне (отметить галочкой).
  8. Для сборки - нажать кнопку "Copy", LibraryCollector скопирует все выбранные библиотеки с учетом необходимой вложенности/иерархии папок.

Вы можете менять и модифицировать js- cценарии для определения, группировки, копирования библиотек под себя.




3. Теория или принципы работы LibraryCollector.

Библиотеки Qt5 условно можно разделить на:
  1. Модули Qt - соответствуют https://doc.qt.io/qt-5.10/qtmodules.html
    1. Эти библиотеки содержаться в папке QTDIR/bin
    2. Эти библиотеки отображаются таблице импорта исполняемого файла, их можно легко определить проанализировав его.
    3. Раньше поиск/расположение этих библиотек соответствовала стандартным правилам поиска библиотеки в системе
      https://msdn.microsoft.com/ru-... .120).aspx
      Но где-то с Qt 5.5.1 разработчики решили явно зашивать путь внутрь Qt5Core (хардкорно)
      Поэтому при сборке приходится копировать Qt5Core, а затем патчить ее указывая в переменной qt_prfxpath текущую директорию.
      Примечание: в js- сценарии за патчинг отвечает utils.patchFile().
      В более поздних версиях Qt патчинг убрали, не ужели патчинг было неудачное решения? ))
  2. Плагины.
    1. Эти библиотеки содержаться в папке QTDIR/plugins
    2. Особенность плагинов в том что в отличии от модулей они могут грузиться не сразу при запуске программы, а подгружаться по мере необходимости, например при выполнении кода где идет подключение к БД, или при смене элементов интерфейса qml.
      Они не отображаются в таблице импорта исполняемого файла, поэтому возникла необходимость анализа именно запущенного процесса.
    3. Плагины разбросаны/сгруппированы по подпапкам, т.е. есть своя иерархия папок/файлов которую нужно соблюдать при их копировании.

      Примечание: в js-сценарии за копирование файлов отвечает utils.copyFile(libName, toDir, relDir) которая позволяет третьим параметром задать папку относительно которой копировать файлы.
  3. Библиотеки qml.
    1. Эти библиотеки содержаться в папке QTDIR/qml.
    2. То что касается плагинов так же касается и qml библиотек.
    3. В отличии от плагинов для нормальной подгрузки требуется еще файлы qmldir, по этому их тоже приходится искать и копировать.
  4. Исполняемый файл QtWebEngineProcess и файлы из папки QTDIR/resources необходимы при использовании Qt WebEngine.

    Примечание: в LibraryCollector необходимость копирования QtWebEngineProcess определяется наличием Qt5WebEngineCore,Qt5WebEngineWidgets в зависимостях

И так LibraryCollector что бы определить все используемое анализирует Ваш процесс используя системные функции (Windows) и просматривая системные файлы (Linux), получая список подгруженных библиотек раскидывает их по группам.
Для определения принадлежности библиотеки к группе модулей,плагинам и qml- библиотекам производится сравнение полных путей на предмет вложенности в QTDIR/bin, QTDIR/plugins, QTDIR/qml соответственно.

Примечание: в js-сценарии для проверки вложенности используется utils.isSubPath()

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

4. Настройка QtCreator для запуска LibraryCollector как внешней утилиты.

LibraryCollector можно запускать из QtCreator, для этого нужно лишь добавить его во внешние утилиты:

Нажмите на изображение для увеличения
Название: Инструменты-Внешние-Настроить.jpg
Просмотров: 3857
Размер:	92.8 Кб
ID:	4743Нажмите на изображение для увеличения
Название: Параметры.jpg
Просмотров: 3259
Размер:	266.7 Кб
ID:	4744

Поля для заполнения:

Программа:
Code
1
D:\LibraryCollector_deploy\LibraryCollector.exe
Параметры:
Code
1
%{CurrentProject:BuildPath} %{CurrentBuild:Name} %{CurrentProject:FileBaseName} %{CurrentProject:QT_HOST_BINS}
Рабочий каталог:
Code
1
D:\LibraryCollector_deploy
5. Js -сценарий

Js - сценарий придает гибкости LibraryCollector и дает возможность изменить поведение сборки для определенных приложений.

Скрипт должен содержать три функции которые будут вызываться в процессе работы LibraryCollector, и примерно должен выглядеть так:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function init()
{
/* Ваш код инициализации, тут можно определить на какие группы 
   будем распределять библиотеки  */
}
 
function update(libs)   // libs - список библиотек
{
/* Тут должен быть код анализа и распределения библиотек по группам
*/
}
 
function copy(toDir) // toDir папка в которую нужно собирать.
{
/* Код копирования библиотек*/
}
init() вызывается при смене скрипта в выпадающем списке, а так же при на кнопку "Clear".
update() и copy() вызываются при нажатии на соответствующие кнопки.

Внутри скрипта доступны следующие глобальные объекты:
  • log- дает возможность выводить сообщение в окно лога LibraryCollector
    Например:
    JavaScript
    1
    
    log.addInfo("hello!","green");
    JavaScript
    1
    
    log.addError('ups!')
  • tree -дерево зависимостей, позволяет выводить библиотеки.
    Например:
    JavaScript
    1
    2
    
        var binGroupIndex = tree.addGroup("bin") 
                   // добавление группы "bin", возвращает индекс созданной группы
    JavaScript
    1
    
        tree.clearGroups(); // Удаление групп
    JavaScript
    1
    2
    3
    4
    5
    6
    7
    8
    
      // Проход по дереву (группа-библиотека)
      for (var groupIndex = 0; groupIndex < tree.groupCount(); ++groupIndex)
            for (var libIndex = 0; libIndex < tree.libCount(groupIndex); ++libIndex)
                if (tree.libIsChecked(groupIndex, libIndex))
                {
                    var groupName = tree.groupName(groupIndex);
                    var libName = tree.libName(groupIndex, libIndex);
                }
  • QTDIR - путь к Qt
  • utils - собраны разные функции, например:
    JavaScript
    1
    
    utils.isSubPath(QTDIR + '/plugins', lib) // Проверка принадлежности библиотеки к плагинам
    JavaScript
    1
    2
    3
    4
    5
    6
    
    // Копирование библиотеки
        var newFileName = utils.copyFile(libName, toDir, relDir);
        if(!newFileName)
        {
             log.addError('Error: Can`t copy file "' + libName + '" to "' + toDir + '"');
        }
  • FileInfo, Dir - аналоги QFileInfo, QDir.

    Более подробную информацию по объектам можно получить посмотрев исходники из папки wrappers



Ссылки:

1. Hard-coded пути в QtCore.dll
2. Qt 5.1 и корректный deployment в Windows
3. Запуск Qt приложений .exe вне Qt Creator

Блоги:

1. Деплой Qt5 приложений в Windows. Скандалы, интриги, расследования.

Темы:

Windows:
1. Поиск окна
2. Захват кнопкой курсора как в Spy++
3. Qt5 Перенос приложения на другой компьютер

Linux:
1. Получить список загруженных библиотек конкретного процесса
2. Поиск окна под курсором
3. Копирование файла и его сим.линка (Linux)


Исходники:

Последняя версия: https://github.com/Avazart/LibraryCollector

Готовые сборки программы:
Вложения
Тип файла: zip LibraryCollector_deploy_win64_MSVC2019_Qt6.1.2.zip (12.06 Мб, 4313 просмотров)
Размещено в C++, C++Qt
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 1
Комментарии
  1. Старый комментарий
    Аватар для Avazart
    Пересобрал под Qt6 для x64 деплой программы во вложениях.
    Запись от Avazart размещена 15.08.2021 в 21:49 Avazart вне форума
 
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru