понедельник, 17 сентября 2012 г.

Патчи на Qt 4.8.2-4.8.5 для Windows

Я задался вопросом как уменьшить размер Qt библиотек для Windows платформы, оставив только то, что реально используется. Это нужно по понятной причине: в Windows все программы вынуждены таскать все свои зависимости с собой. Это значит, что если у вас установлено 5 программ, написанных на Qt, все пять будут содержать копию Qt библиотек в своём каталоге. Место на диске уменьшится при этом существенно. Вторая причина - это скорость запуска. Чем меньше размер dll библиотек, тем быстрее грузится программа. Поэтому я решил уменьшить размер Qt хотя бы для своей программы.

Как оказалось, не всё так просто. Некоторые вещи, которые можно отключить в qconfig, нельзя отключать по причине ошибок компиляции Qt. Я написал несколько патчей, которые снимают некоторые (но не все) ограничения по компиляции Qt, и добавляют некоторую новую функциональность.

 Патчи подходят для Qt 4.8.2, 4.8.3, 4.8.4 и 4.8.5.
  • qt-4.8.2-add-some-features.diff - добавляет возможность отключить в qconfig QMatrix2x2, QVector2D, QVector3D, QVector4D, QQuaternion, QTessellator, QFormLayout, все модели SQL, QPlainTextEdit, QIdentityProxyModel
  • qt-4.8.2-allow-combobox-without-linedit.diff - разрешает QComboBox без QLineEdit, то есть убирает зависимость QComboBox от QLineEdit. Но если QLineEdit выключен, то QComboBox теряет возможность быть редактируемым
  • qt-4.8.3-fixes.diff (для 4.8.5: qt-4.8.5-fixes.diff) - исправления компиляции QApplication, Windows стилей, QWidget, QHttpThreadDelegate, QWinInputContext, QImageReader, QAxServerBase, когда отключены некоторые компоненты (например, IM). Исправление логики в QSettings с IniFormat, когда QTemporaryFile отключён
  • qt-4.8.3-qfiledialog.diff - если выключен QFileDialog, то статические методы getOpenFileName() и getSaveFileName() остаются доступными, т.к. они используют Win32 API для диалогов открытия файла (если вы при этом используете QFileDialog::DontUseNativeDialog, то программа упадёт с фатальной ошибкой)
  • qt-4.8.3-remove-some-qrc.diff - убирает из Qt qrc файлы для QPrintDialog и QCommonStyle. Используйте этот патч, если вы отключили QPrintDialog и если встроенные pixmap-ы для QCommonStyle вам не нужны (скорее всего, что не нужны)
  • qt-4.8.2-remove-timeline-and-easingcurve.diff - если выключен ANIMATION, то убирает также классы QEasingCurve и QTimeLine

Также были найдены следующие особенности классов:
  • если отключён формат BMP, то QClipboard::setPixmap() перестаёт работать. Это недокументировано, но данный метод на Win32 платформе использует родной для Windows BMP формат чтобы занести QPixmap в буфер обмена. Если BMP формат отключён, то этот метод не работает
  • нельзя отключать FILESYSTEMITERATOR, т.к. от него зависит QCoreApplication. Я не смог исправить эту зависимость 
  • если отключён DRAGANDDROP, то QClipboard::setText() просто опустошает буфер обмена, не занося в него никакого текста. Это происходит потому, что отключение DND влечёт за собой отключение некоторых mime типов, и QClipboard теряет возможность занести в буфер обмена обычный текст
  • Классы из ActiveQt используют классы QAction, QMenuBar, QStatusTip и QStatusBar. Если вы отключите последние, то компонент activeqt просто не соберётся. Чтобы убрать эту зависимость пришлось бы серьёзно патчить ActiveQt, я не стал рисковать

Этапы сборки нашей версии Qt:
  1. наложение патчей на дерево исходных кодов Qt
  2. запуск утилиты qconfig.exe, отключение ненужных компонентов, сохранение
  3. компиляция Qt с параметром -qconfig (используйте jom для ускорения компиляции)

Какими ключами пользуюсь я:

configure.exe -qconfig tht -release -opensource -nomake demos -nomake examples -nomake tools -no-qt3support -no-libtiff -no-libmng -no-phonon -no-multimedia -no-audio-backend -no-webkit -no-script -no-scripttools -no-declarative -no-declarative-debug -no-opengl -no-xmlpatterns -qt-style-windowsxp -qt-style-windowsvista -plugin-sql-sqlite -confirm-license


Ссылки:

6 комментариев:

Анонимный комментирует...

>Некоторые вещи, которые можно отключить в qconfig, нельзя отключать по причине ошибок компиляции Qt

Где ссылки на багтрекер или codereview? Эти вещи должны быть исправлены и разработчики Qt их правят сами/могут принять патчи.

Анонимный комментирует...

>Где ссылки на багтрекер или codereview?

Все баги с патчами зафайлены, прогресса пока нет. Возиться с git мне откровенно лениво, это уже перебор.

neval8 комментирует...

А по факту, какой был результат достигнут?

Анонимный комментирует...

git ругается на неправильный формат патча, чем накладывать патчи?

Анонимный комментирует...

>А по факту, какой был результат достигнут?

QtCore - 2Mb
QtGui - 5Mb

Анонимный комментирует...

>git ругается на неправильный формат патча, чем накладывать патчи?

Патчи сделаны и накладываются с помощью утилиты GNU patch. Какой формат патча ожидает git понятия не имею.