Qt и кросскомпиляция в Kubuntu 9.04. Заметка 1.

Естественно тема обсуждалась многими и во многих местах, но каждый из нас тратил время чтобы изучить новую для себя технологию, или вспомнить старое. Эту заметку я надумал тут оставить хотя бы для себя, чтобы без лишних мучений заново настроить свой Qt если все заново придется настраивать если конфиги растеряю.
Уже больше года занимаясь программированием на Qt, я давно планировал купить Windows, дабы компилировать на нем лицензионные программы под эту платформу. Windows был бы нужен только для компиляции и ни для чего больше. Все что меня интересует я давно нашел в линуксе.
Краем уха слышал что лазарус поддерживает кросскомпиляцию, но не удивился, при их подходе все пихать в бинарник - это вполне естественно, подумал я. Но в один прекрасный день я открыл nigma.ru и вбил туда "кросскомпиляция Qt". С этого и началась вся история...

Во-первых, я использую qt-sdk, да так, чтобы в нем никаких либов от kde не подгружалось без спроса, ибо либы эти - gpl, а это для меня не желательно. Лежит SDK в папке: /opt/qtsdk-2009.03 . Будем считать что ваш qt-sdk лежит в той же папке. Тогда у вас должна быть и такая папка: /opt/qtsdk-2009.03/qt/mkspecs/win32-g++. Там лежат спеки для компиляции в mingw. Для настройки спека на кросскомпиляцию достаточно поправить файл qmake.conf, лежащий в этой папке, для этого достаточно изменить следующие строки:
QMAKE_CXX = i586-mingw32msvc-g++

QMAKE_INCDIR = /usr/i586-mingw32msvc/include/
QMAKE_INCDIR_QT = /wine_c/Qt/2009.03/qt/include/
QMAKE_LIBDIR_QT = /wine_c/Qt/2009.03/qt/lib/

QMAKE_LINK = i586-mingw32msvc-g++
QMAKE_LFLAGS = -mthreads -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import \
   -Wl,-enable-runtime-pseudo-reloc -mwindows

QMAKE_DIR_SEP = /
QMAKE_COPY = cp
QMAKE_COPY_DIR = cp -r
QMAKE_MOVE = mv
QMAKE_DEL_FILE = rm -f
QMAKE_MKDIR = mkdir -p
QMAKE_DEL_DIR = rm -rf

QMAKE_RC = i586-mingw32msvc-windres

QMAKE_ZIP = zip -r -9

QMAKE_STRIP = i586-mingw32msvc-strip

Но это конечно же не следует делать бездумно. Бинарники i586-mingw32msvc-strip, i586-mingw32msvc-g++ и т.д. должны быть установлены. Для этого необходимо открыть пакетный менеджер и поставить пакеты: mingw32, mingw32-binutils, mingw32-runtime.
Папки: /wine_c/Qt/2009.03/qt/include/ и /wine_c/Qt/2009.03/qt/lib/ - это папки инклудов и библиотек windows-версии Qt, которые могут быть установлены посредством установки windows версии qt-sdk через wine, при этом в ыше предполагалось, что /wine_c - это ссылка на папку ~/.wine/dosdevices/c\:, то есть на диск c.
Итак, если все сделано правильно, то для компиляции windows-приложения достаточно в папке с проектным файлом выполнить:
/opt//qtsdk-2009.03/qt/bin/qmake -spec win32-g++
make

Все это довольно просто, хотя этот мануал и не позволит вам вслепую копировать приведенный алгоритм. Разве что вы поставите qt в папку /opt/qtsdk-2009.03/ и сделаете ссылку /wine_c, тогда прямое выполнения алгоритма задачу решит, но не иначе.

Это лишь первая заметка о кросскомпиляции, в последующих будет рассмотрено:

Qt и кросскомпиляция в Kubuntu 9.04. Заметка 2.

В предыдущей статье я рассказал о том как скомпилировать windows-приложение в linux, осталось его запустить и проверить его работоспособность.
В принципе в запуске ничего сложного нет, просто приложение будет требовать наличия динамических библиотек Qt и mingw. Это следующие библиотеки:
mingwm10.dll
QtCore4.dll
QtGui4.dll
...

Думаю логика ясна, если используете QtGui, приложите библиотеку, также поступать с QtScript, QtSvg, QtSql и т.д.
Берут эти библиотеки из windows-сборки qt, в сдк это в подпапках bin и mingw.
Библиотеки можно класть в рабочую папку приложения, т.е. ту, которая будет текущей при его запуске. Но это породит дублирование, возможно прочие проблемы. С другой стороны, вы уже будете наглядно видеть, от чего программа зависит и оценить размер дистрибутива.
Если же библиотеки положить в C:\windows\system32, то они будут доступны для всех ваших приложений. Возможно это будет проще. Если вспомнить что речь идет о linux и wine, а не windows, то путь до папки system32, конечно же, другой. Выглядит он примерно так:
~/.wine/dosdevices/c\:/windows/system32
Итак, все библиотеки лежат там, где их ищет wine, значит можно запускать приложение:
wine <имя программы>
Отмечу, что в моей системе программа еще и так запускается:
./<имя программы>
это очень важный момент, т.к. он сыграет большую роль в дальнейшем. Возможно это достигается обычной установкой wine, а может быть требует дополнительных манипуляций. Сейчас я точно сказать не могу. Надеюсь пара комментариев на эту тему позволит сказать точно.
Итак, приложение скомпилировано и запускается в wine, что позволяет быстро проверить его работоспособность и поведение не переключаясь на windows, кстати, если есть желание придать приложению более приятный вид, попробуйте запустить его так:
wine <имя программы> -style cleanlooks
или так:
wine <имя программы> -style plastique
конечно это не лучший вариант, но все же.

Следующим, на мой взгляд, интересным вопросом является кросскомпиляция в QtCreator. По крайней мере я работаю именно в этой IDE и для меня такая возможность является приятным моментом.
Откройте интересующий вас проект в QtCreator и переключитесь в режим "Проекты" (скорее всего нужно нажать Ctrl+4). В списке открытых проектов выберите свой. Выбрав настройки сборки, добавьте новую:

Задайте имя новой сборки, включите флажок "Фоновая сборка" и укажите папку, в которой она будет осуществляться, это позволит не стирать объектные файлы, Makefile'ы и прочие файлы других сборок(сборок под линукс например).
Далее выберите "Этапы сборки":

Выберите этап QMake, в дополнительных параметрах укажите: "-spec win32-g++"
В принципе, для компиляции этого вполне достаточно, просто выбираете режим сборки и компилируете, только вот запускаться программа не будет. Дело в том, что QtCreator пытается запустить файл с именем <имя программы>, а результатом компиляции является файл <имя программы>.exe... Но не все так страшно.

QtCreator позволяет добавить свой этап сборки, для этого нажмите кнопку с плюсом под этапами сборки и выберите "Custom Process Step" как на рисунке, позаботьтесь о том, чтобы новый этап выполнялся последним(перемещайте его стрелками вверх и вниз). Суть этого этапа также отражена на рисунке, фактически вы переименовываете файл <имя программы>.exe с помощью команды /bin/mv. Итак: название этапа - любое, команда - /bin/mv, рабочий каталог - "каталог сборки windows версии", параметры - "<имя программы>.exe <имя программы>".
Теперь QtCreator найдет тот бинарник, который он ищет и запустит его командой - ./<имя программы>, у меня это работает, хочется верить, что сработает и у вас.

В следующей заметке: компиляция dll, настройка postgresql и qwt