Цель статьи
Документирование получения системы кросс-компиляции под Linux для Windows x32/x64/static/shared и сборка последней на момент описания Qt 5.4.1 в лайт-версии (для указанных четырех целей). Для себя, глубоко-обожаемого, ну и для пользы обществу.
Назначение
Многие разработчики приходят к выводу, что использование *nix (в частности Linux) более предпочтительно для разработки приложений, используя фрэймворк Qt. И тому есть причины. Qt изначально ориентирована на *nix инструментарий, типа autotool, make, perl… И второй момент, под никсами есть прекрасный инструмент — valgrind, под виндой порта пока его не видел. Ну и последняя причина: просто удобно иметь набор инструментария для создания приложений под различные целевые платформы — в одном месте.
Почему лайт-версия Qt5
Фрэймворк-Qt имеет модульную структуру, но, увы, не совсем совершенную. Некоторые зависимости от внешних библиотек «вешаются» не на модуль, требующий эти библиотеки, а на Qt5Core. Иными словами, нужна вам эта библиотека, или нет — вынь да положЪ в дистрибутив. Пример тому «монстрик» — библиотека ICU. Весит она почти 25 метров! Зависимость вешается, как я упоминал выше, на Qt5Core… а требует ее модуль Qt5WebKit (который по сути в 99% случаев не используется, по крайней мере мной). Что делаем? Вырезаем и отрезаем. Хотите получить фулл-версию Qt5? Об этом упомяну в заключении. Поехали.
0. Сценарий сборки
Все шаги делаем последовательно. Желательно не объединять все скрипты в последовательную сборку по причине необходимости промежуточного «человечного» контроля. Разные дистрибутивы Линуха, разные среды исполнения, наборы инструментариев… Простой алгоритм: сделал очередной шаг, убедился в отсутствии ошибок, пошел делать следующий. Итак, сам сценарий:
- 1. Предварительная подготовка
- 2. Установка среды кросс-компиляции MXE
- 3. Загрузка и настройка Qt 5.4.1
- 4. Сборка комплектов Qt 5.4.1 для четырех целей (см. сабж)
- 5. Прописка собранного в QtCreator
1. Предварительная подготовка
У вас установлен дистрибутив Линукса. Желательно все это делать на на продакшен-компе (не на живом Линуксе), а установленном в виртуальную машину. Я например, пользуюсь VMWare, но это дело вкуса. Выбор дистрибутива Линукса — так же дело вкуса. Лично я предпочитаю Gentoo Linux, собственно под ним всю эту кухню и настраиваю. Если есть сложности в настройке, у меня есть небольшая статейка по этому вопросу: «Установка и настройка Linux Gentoo под VMWare».
Итак, у вас есть настроенный Линукс и вы работаете не под рутом! Для дальнейшей работы вам нужно проверить присутствие следующих установленных пакетов, или доустановить:
$ sudo emerge \
app-arch/bzip2 \
app-arch/unzip \
app-arch/xz-utils \
app-shells/bash \
dev-lang/ruby \
dev-libs/libffi \
dev-libs/openssl \
dev-perl/XML-Parser \
dev-util/cmake \
dev-util/intltool \
dev-util/pkgconfig \
dev-util/scons \
dev-vcs/git \
sys-devel/autoconf \
sys-devel/automake \
sys-devel/bison \
sys-devel/flex \
sys-devel/gettext \
sys-devel/libtool \
sys-devel/patch \
net-misc/ntp \
www-client/lynx
Вся дальнейшая установка будет производиться в каталог $HOME/dev. Если у вас таковой присутствует — либо переименовываете его, либо внимательно правите скрипты, которые будут приведены далее. Для всех манипуляций со скачиваемыми внешними файлами/скриптами/библиотеками будет использован каталог $HOME/setup. Все замечания выше относительно $HOME/dev — в силе и к этому каталогу.
2. Установка среды кросс-компиляции MXE
Предварительное замечание об MXE. Это отличнейшая система сборки тулчейнов для кросс-компиляции. Но есть одно «но». В данный момент не существует стабильной ветки. Авторы до поры до времени вели две ветки в своем git-репозитарии — стабильную и «разработческую». Сейчас ветки объединены. Разработка идет ну очень активно — изменения сбрасываются чуть ли не раз 1-3 дня. А это чревато тем, что «то работает сборка, то не работает». Некоторые важные для меня библиотеки, в частности клиентская часть PostgreSQL, собираются без ошибок, но в нерабочем состоянии. Потратил неделю не исследование явных косяков. Исправляем эти «недочеты». Итак:
$ mkdir -p $HOME/setup
$ cd $HOME/setup
$ wget http://majestio.tk/stuff/setup-scripts.tar.xz
$ tar -xf setup-scripts.tar.xz
$ rm -f setup-scripts.tar.xz
Должны получить в каталоге $HOME/setup следующий набор скриптов:
1.setup-first.sh
#!/bin/sh
###########################################################################
## ##
## Скрипт 1. Создание структуры каталогов для разворачивания системы ##
## кросс-компиляции средствами MXE (http://mxe.cc), ##
## собственно загрузку и первоначальную сборку ##
## ##
## Majestio (C) http://majestio.tk ##
###########################################################################
#
# Порядок установки:
#
# 1. Создать в $HOME подкаталог, например $HOME/Setup
# 2. Скопировать туда этот скрипт и запустить
# 3. Дождаться завершения
#
# Структура подкаталогов будет в $HOME/dev
# Набор тулчейнов MXE ищем в $HOME/dev/cross/mxe
#
# .........................................................................
if [ "$(whoami)" == 'root' ]; then
echo "Ахтунг: под учетной записью рута работать отказываюсь!"
exit 1
fi
RETDIR=`pwd`
MXEHOME=$HOME/dev/cross/mxe
# создаем структуру каталогов и вынимаем MXE из git-репозитария -----------
mkdir -p $HOME/dev/{cross,projests,src,stuff,tools}
cd $HOME/dev/cross
# можно так:
# git clone https://github.com/mxe/mxe.git
# но лучше так:
# wget http://majestio.tk/stuff/mxe-empty-26.05.2015.tar.xz
# tar -xf mxe-empty-26.05.2015.tar.xz
# rm -f mxe-empty-26.05.2015.tar.xz
wget http://majestio.tk/stuff/mxe-empty-26.05.2015.tar.xz
tar -xf mxe-empty-26.05.2015.tar.xz
rm -f mxe-empty-26.05.2015.tar.xz
# патчим файлик определения ABI проекта MXE -------------------------------
echo "#!/bin/sh" > $HOME/dev/cross/mxe/ext/config.guess
echo "echo \"x86_64-pc-linux-gnu\"" >> $HOME/dev/cross/mxe/ext/config.guess
# делаем первоначальную сборку MXE с типом нитей win32 --------------------
cd $MXEHOME
make MXE_TARGETS='x86_64-w64-mingw32.shared '`
`'x86_64-w64-mingw32.static '`
`'i686-w64-mingw32.shared '`
`'i686-w64-mingw32.static ' gcc gmp winpthreads -j4 JOBS=4
# патчим mxe/src/gcc.mk на предмет добавления posix-threads ---------------
GCCMK=$MXEHOME/src/gcc.mk
PLTMP=$$-$RANDOM.pl
echo "open(F,\"$GCCMK\") || die \"Holy shit!\\n\";" > $PLTMP
echo "@In = <F>;" >> $PLTMP
echo "close(F);" >> $PLTMP
echo "open(F,\">$GCCMK\") || die \"Holy shit!\\n\";" >> $PLTMP
echo "foreach \$I(@In) {" >> $PLTMP
echo " \$I =~ s/^(\\\$\(PKG\)_DEPS.+)\$/\$1 winpthreads/;" >> $PLTMP
echo " \$I =~ s/^(.+?--libdir='\\\$\(PREFIX\).+)\$/\$1\n --enable-shared=libstdc\+\+ \\\/;" >> $PLTMP
echo " \$I =~ s/^(.+?--enable-threads=)win32(.*)\$/\$1posix\$2/;" >> $PLTMP
echo " print F \$I;" >> $PLTMP
echo "}" >> $PLTMP
echo "close(F);" >> $PLTMP
perl $PLTMP && rm -f $PLTMP
# пересобираем GCC с поддержкой posix-threads -----------------------------
cd $MXEHOME
make MXE_TARGETS='x86_64-w64-mingw32.shared '`
`'x86_64-w64-mingw32.static '`
`'i686-w64-mingw32.shared '`
`'i686-w64-mingw32.static ' gcc -j4 JOBS=4
# делаем промежуточный архив "пустой" системы кросс-компиляции ------------
echo "Делаем промежуточную архивацию ..."
cd ..
tar -cJf mxe-winpthreads-empty.tar.xz ./mxe
# собираем дополнительные либы --------------------------------------------
cd $MXEHOME
make MXE_TARGETS='x86_64-w64-mingw32.shared '`
`'x86_64-w64-mingw32.static '`
`'i686-w64-mingw32.shared '`
`'i686-w64-mingw32.static ' zlib xz sqlite dbus \
libiconv libodbc++ -j4 JOBS=4
# патчим и собираем PostgreSQL --------------------------------------------
cd $MXEHOME/src
wget http://majestio.tk/stuff/postgresql-3-socket.patch
PQSQL=$MXEHOME/src/postgresql.mk
PLTMP=$$-$RANDOM.pl
echo "open(F,\"$PQSQL\") || die \"Holy shit!\\n\";" > $PLTMP
echo "@In = <F>;" >> $PLTMP
echo "close(F);" >> $PLTMP
echo "open(F,\">$PQSQL\") || die \"Holy shit!\\n\";" >> $PLTMP
echo "foreach \$I(@In) {" >> $PLTMP
echo " \$I =~ s/^(.+?--disable-rpath.+)\$/\$1\n --disable-thread-safety \\\/;" >> $PLTMP
echo " print F \$I;" >> $PLTMP
echo "}" >> $PLTMP
echo "close(F);" >> $PLTMP
perl $PLTMP && rm -f $PLTMP
cd $MXEHOME
make MXE_TARGETS='x86_64-w64-mingw32.shared '`
`'x86_64-w64-mingw32.static '`
`'i686-w64-mingw32.shared '`
`'i686-w64-mingw32.static ' postgresql -j4 JOBS=4
for PREFIX in "x86_64-w64-mingw32.shared" "x86_64-w64-mingw32.static" \
"i686-w64-mingw32.shared" "i686-w64-mingw32.static" ; do
echo "Description: PostgreSQL libpq library" > $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
echo "Url: http://www.postgresql.org/" >> $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
echo "Version: 9.2.4" >> $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
echo "Requires: " >> $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
echo "Requires.private: " >> $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
echo "Cflags: -I$MXEHOME/usr/$PREFIX/include" >> $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
echo "Libs: -L$MXEHOME/usr/$PREFIX/lib -lpq" >> $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
echo "Libs.private: -lssl -lcrypto -lshell32 -lwsock32 -lws2_32 -lsecur32" >> $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
chmod 0644 $MXEHOME/usr/$PREFIX/lib/pkgconfig/libpq.pc
done
cd $RETDIR
2.setup-qt5.sh
#!/bin/sh
###########################################################################
## ##
## Скрипт 2. Выкачка Qt 5.4.1 + небольшие косметические правки ##
## ##
## Majestio (C) http://majestio.tk ##
###########################################################################
#
# Порядок установки:
#
# 1. Зайти в каталог установки $HOME/Setup
# 2. Скопировать туда этот скрипт и запустить
# 3. Дождаться завершения
#
# На выходе будет каталог qt5
#
# -------------------------------------------------------------------------
if [ "$(whoami)" == 'root' ]; then
echo "Ахтунг: под учетной записью рута работать отказываюсь!"
exit 1
fi
wget http://download.qt.io/official_releases/qt/5.4/5.4.1/single/qt-everywhere-opensource-src-5.4.1.tar.gz
tar -xf qt-everywhere-opensource-src-5.4.1.tar.gz
mv qt-everywhere-opensource-src-5.4.1 qt5
cd qt5/qtbase/mkspecs
wget http://majestio.tk/stuff/win32-g++.static.tar.xz
tar -xf win32-g++.static.tar.xz
rm -f win32-g++.static.tar.xz
cd ../..
wget http://majestio.tk/stuff/qt-5.4.1.patch
patch -p1 -u < qt-5.4.1.patch
rm -f qt-5.4.1.patch
cd ..
3.1.build-qt-x32-shared.sh
#!/bin/sh
###########################################################################
## ##
## Скрипт 3.1 Создание сборки Qt 5.4.1 для Win x32 (shared) ##
## ##
## Majestio (C) http://majestio.tk ##
###########################################################################
#
# Порядок установки:
#
# 1. Зайти в каталог установки $HOME/Setup
# 2. Скопировать туда этот скрипт и запустить
# 3. Дождаться завершения
#
# На выходе будет готовая сборка, размещенная в %HOME/dev/stuff
#
# -------------------------------------------------------------------------
if [ "$(whoami)" == 'root' ]; then
echo "Ахтунг: под учетной записью рута работать отказываюсь!"
exit 1
fi
TARGET="i686-w64-mingw32.shared"
MXE="$HOME/dev/cross/mxe/usr"
PREFIX="$HOME/dev/stuff/qt5-$TARGET"
export PATH=$MXE/bin:$PATH
PWD="`pwd`"
LOG="$PWD/$TARGET-qt5.log___________"
mkdir "$TARGET-qt5.build"
cd "$TARGET-qt5.build"
clear
OPENSSL_LIBS="`''"$TARGET"'-pkg-config' --libs-only-l openssl`" \
PSQL_LIBS="-lpq -lsecur32 `''"$TARGET"'-pkg-config' --libs-only-l openssl` -lws2_32" \
../qt5/configure -prefix $PREFIX \
-opensource \
-confirm-license \
-release \
-shared \
-opengl desktop \
-force-pkg-config \
-no-use-gold-linker \
-no-glib \
-openssl \
-dbus \
-plugin-sql-psql \
-plugin-sql-sqlite \
-plugin-sql-odbc \
-qt-libpng -qt-libjpeg -qt-pcre -zlib -qt-freetype -no-kms -no-pch \
-nomake examples -nomake tests -silent -skip webkit \
-xplatform win32-g++ \
-device-option CROSS_COMPILE=$TARGET- \
-device-option PKG_CONFIG="$TARGET-pkg-config" 2>&1 | tee $LOG
make -j4 2>&1 | tee -a $LOG
make install 2>&1 | tee -a $LOG
3.2.build-qt-x32-static.sh
#!/bin/sh
###########################################################################
## ##
## Скрипт 3.2 Создание сборки Qt 5.4.1 для Win x32 (static) ##
## ##
## Majestio (C) http://majestio.tk ##
###########################################################################
#
# Порядок установки:
#
# 1. Зайти в каталог установки $HOME/Setup
# 2. Скопировать туда этот скрипт и запустить
# 3. Дождаться завершения
#
# На выходе будет готовая сборка, размещенная в %HOME/dev/stuff
#
# -------------------------------------------------------------------------
if [ "$(whoami)" == 'root' ]; then
echo "Ахтунг: под учетной записью рута работать отказываюсь!"
exit 1
fi
TARGET="i686-w64-mingw32.static"
MXE="$HOME/dev/cross/mxe/usr"
PREFIX="$HOME/dev/stuff/qt5-$TARGET"
PWD="`pwd`"
LOG="$PWD/$TARGET-qt5.log___________"
mkdir "$TARGET-qt5.build"
cd "$TARGET-qt5.build"
clear
export PATH=$MXE/bin:$PATH
#../qt5/configure --help|less
#exit
OPENSSL_LIBS="`''"$TARGET"'-pkg-config' --libs-only-l openssl`" \
PSQL_LIBS="-lpq -lsecur32 `''"$TARGET"'-pkg-config' --libs-only-l openssl` -lws2_32" \
../qt5/configure -prefix $PREFIX \
-opensource \
-confirm-license \
-release \
-static \
-opengl desktop \
-force-pkg-config \
-no-use-gold-linker \
-no-glib \
-openssl-linked \
-dbus-linked \
-qt-sql-psql \
-qt-sql-sqlite \
-qt-sql-odbc \
-qt-libpng -qt-libjpeg -qt-pcre -zlib -qt-freetype -no-kms -no-pch \
-nomake examples -nomake tests -silent -skip webkit \
-xplatform win32-g++ \
-device-option CROSS_COMPILE=$TARGET- \
-device-option PKG_CONFIG="$TARGET-pkg-config" 2>&1 | tee $LOG
make -j4 2>&1 | tee -a $LOG
make install 2>&1 | tee -a $LOG
3.3.build-qt-x64-shared.sh
#!/bin/sh
###########################################################################
## ##
## Скрипт 3.3 Создание сборки Qt 5.4.1 для Win x64 (shared) ##
## ##
## Majestio (C) http://majestio.tk ##
###########################################################################
#
# Порядок установки:
#
# 1. Зайти в каталог установки $HOME/Setup
# 2. Скопировать туда этот скрипт и запустить
# 3. Дождаться завершения
#
# На выходе будет готовая сборка, размещенная в %HOME/dev/stuff
#
# -------------------------------------------------------------------------
if [ "$(whoami)" == 'root' ]; then
echo "Ахтунг: под учетной записью рута работать отказываюсь!"
exit 1
fi
TARGET="x86_64-w64-mingw32.shared"
MXE="$HOME/dev/cross/mxe/usr"
PREFIX="$HOME/dev/stuff/qt5-$TARGET"
export PATH=$MXE/bin:$PATH
PWD="`pwd`"
LOG="$PWD/$TARGET-qt5.log___________"
mkdir "$TARGET-qt5.build"
cd "$TARGET-qt5.build"
clear
OPENSSL_LIBS="`''"$TARGET"'-pkg-config' --libs-only-l openssl`" \
PSQL_LIBS="-lpq -lsecur32 `''"$TARGET"'-pkg-config' --libs-only-l openssl` -lws2_32" \
../qt5/configure -prefix $PREFIX \
-opensource \
-confirm-license \
-release \
-shared \
-opengl desktop \
-force-pkg-config \
-no-use-gold-linker \
-no-glib \
-openssl \
-dbus \
-plugin-sql-psql \
-plugin-sql-sqlite \
-plugin-sql-odbc \
-qt-libpng -qt-libjpeg -qt-pcre -zlib -qt-freetype -no-kms -no-pch \
-nomake examples -nomake tests -silent -skip webkit \
-xplatform win32-g++ \
-device-option CROSS_COMPILE=$TARGET- \
-device-option PKG_CONFIG="$TARGET-pkg-config" 2>&1 | tee $LOG
make -j4 2>&1 | tee -a $LOG
make install 2>&1 | tee -a $LOG
3.4.build-qt-x64-static.sh
#!/bin/sh
###########################################################################
## ##
## Скрипт 3.4 Создание сборки Qt 5.4.1 для Win x64 (static) ##
## ##
## Majestio (C) http://majestio.tk ##
###########################################################################
#
# Порядок установки:
#
# 1. Зайти в каталог установки $HOME/Setup
# 2. Скопировать туда этот скрипт и запустить
# 3. Дождаться завершения
#
# На выходе будет готовая сборка, размещенная в %HOME/dev/stuff
#
# -------------------------------------------------------------------------
if [ "$(whoami)" == 'root' ]; then
echo "Ахтунг: под учетной записью рута работать отказываюсь!"
exit 1
fi
TARGET="x86_64-w64-mingw32.static"
MXE="$HOME/dev/cross/mxe/usr"
PREFIX="$HOME/dev/stuff/qt5-$TARGET"
PWD="`pwd`"
LOG="$PWD/$TARGET-qt5.log___________"
mkdir "$TARGET-qt5.build"
cd "$TARGET-qt5.build"
clear
export PATH=$MXE/bin:$PATH
#../qt5/configure --help|less
#exit
OPENSSL_LIBS="`''"$TARGET"'-pkg-config' --libs-only-l openssl`" \
PSQL_LIBS="-lpq -lsecur32 `''"$TARGET"'-pkg-config' --libs-only-l openssl` -lws2_32" \
../qt5/configure -prefix $PREFIX \
-opensource \
-confirm-license \
-release \
-static \
-opengl desktop \
-force-pkg-config \
-no-use-gold-linker \
-no-glib \
-openssl-linked \
-dbus-linked \
-qt-sql-psql \
-qt-sql-sqlite \
-qt-sql-odbc \
-qt-libpng -qt-libjpeg -qt-pcre -zlib -qt-freetype -no-kms -no-pch \
-nomake examples -nomake tests -silent -skip webkit \
-xplatform win32-g++ \
-device-option CROSS_COMPILE=$TARGET- \
-device-option PKG_CONFIG="$TARGET-pkg-config" 2>&1 | tee $LOG
make -j4 2>&1 | tee -a $LOG
make install 2>&1 | tee -a $LOG
Скрипты не будут иметь атрибута «исполняемый» просто в целях безопасности — предотвращения «непреднамеренного случайного» запуска. Запускаем первый скрипт 1.setup-first.sh. Он создаст структуру подкаталогов $HOME/dev…, выкачает систему кросс-компиляции mxe, делает двойную сборку gcc тулчейнов (для обеспечения поддержки posix-threads), соберет основные базовые библиотеки, пропатчит и соберет клиентскую часть библиотеки PostgreSQL.
Важно: Если ваша хостовая система по ABI отличается от «x86_64-pc-linux-gnu», в скрипте вручную удалите патч ABI. Ищем по комментарию «# патчим файлик определения ABI проекта MXE». А лучше пропишете ваш.
$ sh 1.setup-first.sh
3. Загрузка и настройка Qt 5.4.1
Запускаем скрипт 2.setup-qt5.sh. Его задача выкачать исходники Qt 5.4.1, развернуть их в подкаталог qt5/ и пропатчить нужное.
$ sh 2.setup-qt5.sh
4. Сборка комплектов Qt 5.4.1 для четырех целей
Для, собственно, сборки четырех видов Qt 5.4.1 предназначены остальные скрипты:
- 3.1.build-qt-x32-shared.sh
- 3.2.build-qt-x32-static.sh
- 3.3.build-qt-x64-shared.sh
- 3.4.build-qt-x64-static.sh
Запуск производиться точно так же как и в предыдущем пункте:
$ sh скрипт
Однако есть важное замечание, могущее помочь вам сэкономить время на сборку. Если у вас многоядерный компьютер — имеет смысл запускать сборки параллельно. Для этого вы открываете второй(третий, четвертый) терминал, и в терминале запускаете очередной скрипт. Лично мне удобно все действия проводить в дополнительном ssh-клиенте. Как показала практика, на моем Core i7 (4 ядра, с гипертрейдингом) — прирост общего времени сборки наблюдается при двух параллельно работающих сборках. Если более — производительность не возрастает, а чаще всего падает.
Итак, все четыре скрипта отработали. Что мы получили в результате?
$HOME/dev/cross/mxe/usr/bin — тут собраны исполняемые модули всех четырех тулчейнов
$HOME/dev/cross/mxe/usr/тулчейн — тут собраны заголовки и либы тулчейнов
$HOME/dev/stuff/сборки — тут собраны все виды Qt для последующей кросс-компиляции
Осталось все это подключить к использованию.
5. Прописка собранного в QtCreator
Самостоятельно выкачиваете Qt 5.4.1 для вашего линуха (ссылка на x32 или x64), самостоятельно производите установку. Проверяете работоспособность.
После этого регистрируете собранное вами. Открываем QtCreator, выбираем в главном меню «Инструменты» ► «Параметры» ► «Сборка и запуск». Далее, вся регистрация предусматривает три шага:
1) Регистрация компиляторов (Закладка «Компиляторы»)
2) Регистрация профилей Qt (Закладка «Профили Qt»)
3) Регистрация комплектов (Закладка «Комплекты»)
Шаг-1
Добавляя очередной компилятор, выбирайте тип «Особый». Нужный компилятор ищем в $HOME/dev/cross/mxe/usr/bin типа bla-bla-bla-g++. Ниже указываем путь к системной утилите make, типа /usr/bin/make. Далее выставляем ABI. Если выбрали static-версию, внизу добавьте mkspec — «win32-g++.static» (без кавычек). Остальные поля несущественны. Зарегали все четыре вида компиляторов, нажимаем «Применить»
Шаг-2
Переключаемся на закладку «Профили Qt». Добавляя профили ищем их в $HOME/dev/stuff/bla-bla-bla/bin/qmake. Зарегали все четыре профиля, нажимаем «Применить»
Шаг-3
Переключаемся на закладку «Комплекты». Добавляем очередной комплект, выбирая нужный компилятор + профиль Qt. В комплектах, где статическая сборка желательно прописать и mkspecs как на шаге-1. Зарегали все четыре комплекта, нажимаем «Применить»
Заключение
Вполне отдаю себе отчет — собранное может содержать определенные ошибки, т.к. собиралось далеко не автором ни Qt, ни PostgreSQL, даже не участником проекта MXE. Да и отсутствие простейших проверок во время сборки, не говоря уж о юнит-тестах, предполагает, что вы осознаете «сырость» сделанного. Тем не менее, после получения данного набора тулчейнов, я протестировал свои проекты, примеры из поставки Qt. В интересующих меня модулях (UI, PostgreSQL, http, QtScript, и ряда других) ошибок не обнаружил.
… Обещанное про фулл-сборку. Если вам очень повезет, и MXE, на момент вашего интереса будет в стабильном состоянии, получить фулл сборку очень просто:
$ mkdir -p $HOME/dev/{cross,src,stuff,projects}
$ cd $HOME/dev/cross
$ git clone https://github.com/mxe/mxe.git
$ make MXE_TARGETS='x86_64-w64-mingw32.shared' gcc -j4 JOBS=4
$ make MXE_TARGETS='x86_64-w64-mingw32.static' gcc -j4 JOBS=4
$ make MXE_TARGETS='i686-w64-mingw32.shared' gcc -j4 JOBS=4
$ make MXE_TARGETS='i686-w64-mingw32.static' gcc -j4 JOBS=4
#
# чтобы PostgreSQL-либа была рабочей - положите в каталог $HOME/dev/cross/mxe/src
# патчик, полученный из http://majestio.tk/stuff/postgresql-3-socket.patch
#
$ make MXE_TARGETS='x86_64-w64-mingw32.shared' qt5 -j4 JOBS=4
$ make MXE_TARGETS='x86_64-w64-mingw32.static' qt5 -j4 JOBS=4
$ make MXE_TARGETS='i686-w64-mingw32.shared' qt5 -j4 JOBS=4
$ make MXE_TARGETS='i686-w64-mingw32.static' qt5 -j4 JOBS=4
Вангую, по этому варианту сборки вас ждет разочарование с вероятностью 87.14%, но если все будет без косяков, то полученные сборки Qt5 будут размещены в $HOME/dev/cross/mxe/usr/<тулчейн>/qt5
Всем удачного кодинга.
This tutorial shows how to use the QT framework to create a basic application for Windows in Visual Studio and seamlessly port it to Linux. The use of cross-platform QT API ensures that the code written once will run on all platforms supported by QT.
To follow this tutorial you will need the following tools installed:
- Microsoft Visual Studio
- QT Libraries for Visual Studio and the QT Add-in
- VisualGDB 4.1 or later
We will create a basic QT application using the QT wizard, modify the main window, port the application to Linux and demonstrate the use of the cross-platform API provided by QT by listing files in the current directory.
- Start Visual Studio. Begin creating a new project using the QT wizard:
- The first page shows the summary about the created project. Press “next” to proceed:
- The second page allows selecting involved QT modules. Keep the default ones and press “Next”:
- The last page allows customizing the generated class names. We will keep the default ones and press “Finish”:
- The wizard has generated a QT project for Windows. It consists of a .pro file containing various project settings, a .ui file describing the main window and some source files. Press Ctrl-Shift-B to build it:
- Visual Studio will build the project using its own C++ compiler. Press F5 to start debugging it:
- QT framework allows building both Windows and Linux applications from the same source code. To create a new Linux configuration select “Project->Add VisualGDB Configuration->New Linux Configuration”:
- On the first page of the wizard select “qmake” as the build system. This is required to ensure that the QT-specific files, such as .pro and .ui are handled correctly under Linux:
- On the next page select the Linux machine you are targeting. When you build your Linux configuration VisualGDB will transfer the source files to the Linux machine and build them there just like a normal Linux project:
- On the last wizard page you can change the way source files are handled. By default they will be transferred to a subdirectory in /tmp and built there:
- Press “Finish” to complete the wizard. VisualGDB will download the QT Include directories from your Linux machine and configure IntelliSense to parse them:
- Build your new Linux configuration by pressing Ctrl-Shift-B. The Output window will show how the files are transferred to the Linux machine and built there using qmake:
- Set a breakpoint in the constructor of the main window class and press F5 to start debugging. The debugging experience will be similar to debugging normal Windows apps. Additionally to that you can interact with the underlying GDB debugging using the GDB Session pane:
- Press F5 to continue debugging. The program running on the Linux machine will display the main window that will be shown on your Windows machine using the XMing window server. You can also switch to showing the windows on the Linux machine directly via VisualGDB Project Properties:
- Now we will add some functionality to our basic app. Double-click on the .ui file to launch QT Designer. Add a button to the main window:
- Creating a click handler is a bit more complex than using Windows frameworks like MFC, WTL or WPF and requires two steps. First switch to the signal/slot mode (F4) click on the button and drag the signal connector to the form outside the button:
- QT Designer will start creating a new signal/slot connection. A signal is the event produced by the form. A slot is the handler method defined inside your form class:
- Select “clicked()” on the left and click “Edit” on the right to add another slot. Click “+” and type in the new slot name: ButtonClickHandler():
- Press OK to finish creating the connection. Verify the results in the Configure Connection window:
- The QT Designer will show the newly created
signal/slot connection: - Save the .ui file and close QT Designer. Go back to Visual Studio and add the following code inside the declaration of the QtProject1 class:
protected slots: void ButtonClickHandler();
Then add the body of the method to QtProject1.cpp:
#include <QMessageBox> //... void QtProject1::ButtonClickHandler() { QMessageBox msgBox; msgBox.setText("You have pushed the button!"); msgBox.exec(); }
Note that the method name should match the slot name created in Qt Designer.
Build your project with the new code: - Press F5 to run the project. Click the button you added to see the message box:
- Now we will demonstrate how to use cross-platform QT API. In this tutorial we will list all entries in the current directory and display them in the message box. Include <QtDir> in your .cpp file and replace the body of the button click handler with the following code:
QMessageBox msgBox; QDir currentDir("."); QString fileList = "Files in " + currentDir.absolutePath() + ":\n"; QStringList entries = currentDir.entryList(); foreach(QString fn, entries) { if(fn != tr(".") && fn != tr("..")) { fileList += fn + "\n"; } } msgBox.setText(fileList); msgBox.exec();
Note that foreach is a preprocessor macro defined inside QT to simplify iterating over QT collections.
- Build the project and press F5. You will see the list of files on the Linux machine:
- Now simply select “Debug” from the configuration list, build and press F5 again. The same source code will be built for Windows and will show a Windows message box listing files in the Windows directory:
If you want to add more cross-platform functionality that will work on Windows, Linux and Linux-based systems such as Raspberry PI, simply implement it using QT API that is documented here. The QT framework will abstract out the differences between operating systems and let you write easily portable code.
Распознавание голоса и речи на C#
UnmanagedCoder 05.05.2025
Интеграция голосового управления в приложения на C# стала намного доступнее благодаря развитию специализированных библиотек и API. При этом многие разработчики до сих пор считают голосовое управление. . .
Реализация своих итераторов в C++
NullReferenced 05.05.2025
Итераторы в C++ — это абстракция, которая связывает весь экосистему Стандартной Библиотеки Шаблонов (STL) в единое целое, позволяя алгоритмам работать с разнородными структурами данных без знания их. . .
Разработка собственного фреймворка для тестирования в C#
UnmanagedCoder 04.05.2025
C# довольно богат готовыми решениями – NUnit, xUnit, MSTest уже давно стали своеобразными динозаврами индустрии. Однако, как и любой динозавр, они не всегда могут протиснуться в узкие коридоры. . .
Распределенная трассировка в Java с помощью OpenTelemetry
Javaican 04.05.2025
Микросервисная архитектура стала краеугольным камнем современной разработки, но вместе с ней пришла и головная боль, знакомая многим — отслеживание прохождения запросов через лабиринт взаимосвязанных. . .
Шаблоны обнаружения сервисов в Kubernetes
Mr. Docker 04.05.2025
Современные Kubernetes-инфраструктуры сталкиваются с серьёзными вызовами. Развертывание в нескольких регионах и облаках одновременно, необходимость обеспечения низкой задержки для глобально. . .
Создаем SPA на C# и Blazor
stackOverflow 04.05.2025
Мир веб-разработки за последние десять лет претерпел коллосальные изменения. Переход от традиционных многостраничных сайтов к одностраничным приложениям (Single Page Applications, SPA) — это. . .
Реализация шаблонов проектирования GoF на C++
NullReferenced 04.05.2025
«Банда четырёх» (Gang of Four или GoF) — Эрих Гамма, Ричард Хелм, Ральф Джонсон и Джон Влиссидес — в 1994 году сформировали канон шаблонов, который выдержал проверку временем. И хотя C++ претерпел. . .
C# и сети: Сокеты, gRPC и SignalR
UnmanagedCoder 04.05.2025
Сетевые технологии не стоят на месте, а вместе с ними эволюционируют и инструменты разработки. В . NET появилось множество решений — от низкоуровневых сокетов, позволяющих управлять каждым байтом. . .
Создание микросервисов с Domain-Driven Design
ArchitectMsa 04.05.2025
Архитектура микросервисов за последние годы превратилась в мощный архитектурный подход, который позволяет разрабатывать гибкие, масштабируемые и устойчивые системы. А если добавить сюда ещё и. . .
Многопоточность в C++: Современные техники C++26
bytestream 04.05.2025
C++ долго жил по принципу «один поток — одна задача» — как старательный солдатик, выполняющий команды одну за другой. В то время, когда процессоры уже обзавелись несколькими ядрами, этот подход стал. . .
Прошла компиляция qmake. Предложил собрать.
Qt is now configured for building. To start the build run:nmake.
To reconfigure, run ‘nmake confclean’ and configure.
d:\Raspberry\Qt>nmake
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/bootstrap/ && «C:\Program Files (x86)\Microsoft Visual Stud
io 9.0\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/moc/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/rcc/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/uic/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/corelib/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0\V
C\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
D:/Raspberry/Qt/bin/moc.exe -DQT_SHARED -DBCM_PI -DQT_BUILD_CORE_LIB -DQ
T_NO_USING_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COM
PAT -DQT_USE_QSTRINGBUILDER -DELF_INTERPRETER=\»\» -DQLIBRARYINFO_EPOCROOT -DHB_
EXPORT=Q_CORE_EXPORT -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEX
T -DQT_HAVE_SSE2 -I../../mkspecs/linux-rasp-pi-g++ -I. -I../../include -I/mnt/ra
sp-pi-rootfs/opt/vc/include -I/mnt/rasp-pi-rootfs/usr/include -I/opt/dev/src/qt-
platform-mkspecs/5.0/linux-rasp-pi-g++/header-taint -I../../include/QtCore -Itmp
\rcc\debug_shared -Iglobal -I../../tools/shared -I../3rdparty/zlib -I../3rdparty
/harfbuzz/src -I../3rdparty/md5 -I../3rdparty/md4 -Itmp/moc/debug_shared animati
on/qabstractanimation.h -o tmp/moc/debug_shared/moc_qabstractanimation.cpp
/opt/toolchains/arm-2011.09/bin/arm-none-linux-gnueabi-g++ -c -pipe -g —
Wall -W -D_REENTRANT -fPIC -DQT_SHARED -DBCM_PI -DQT_BUILD_CORE_LIB -DQT_NO_USIN
G_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COMPAT -DQT_
USE_QSTRINGBUILDER -DELF_INTERPRETER=\»\» -DQLIBRARYINFO_EPOCROOT -DHB_EXPORT=Q_
CORE_EXPORT -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HA
VE_SSE2 -I../../mkspecs/linux-rasp-pi-g++ -I. -I../../include -I/mnt/rasp-pi-roo
tfs/opt/vc/include -I/mnt/rasp-pi-rootfs/usr/include -I/opt/dev/src/qt-platform-
mkspecs/5.0/linux-rasp-pi-g++/header-taint -I../../include/QtCore -Itmp\rcc\debu
g_shared -Iglobal -I../../tools/shared -I../3rdparty/zlib -I../3rdparty/harfbuzz
/src -I../3rdparty/md5 -I../3rdparty/md4 -Itmp/moc/debug_shared -o tmp/obj/debug
_shared/qabstractanimation.o animation/qabstractanimation.cpp
Системе не удается найти указанный путь.
NMAKE : fatal error U1077: » : return code ‘0x1’
Stop.
NMAKE : fatal error U1077: ‘cd’ : return code ‘0x2’
Stop.
d:\Raspberry\Qt>nmake
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/bootstrap/ && «C:\Program Files (x86)\Microsoft Visual Stud
io 9.0\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/moc/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/rcc/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/uic/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/corelib/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0\V
C\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
D:/Raspberry/Qt/bin/moc.exe -DQT_SHARED -DBCM_PI -DQT_BUILD_CORE_LIB -DQ
T_NO_USING_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COM
PAT -DQT_USE_QSTRINGBUILDER -DELF_INTERPRETER=\»\» -DQLIBRARYINFO_EPOCROOT -DHB_
EXPORT=Q_CORE_EXPORT -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEX
T -DQT_HAVE_SSE2 -I../../mkspecs/linux-rasp-pi-g++ -I. -I../../include -I/mnt/ra
sp-pi-rootfs/opt/vc/include -I/mnt/rasp-pi-rootfs/usr/include -I/opt/dev/src/qt-
platform-mkspecs/5.0/linux-rasp-pi-g++/header-taint -I../../include/QtCore -Itmp
\rcc\debug_shared -Iglobal -I../../tools/shared -I../3rdparty/zlib -I../3rdparty
/harfbuzz/src -I../3rdparty/md5 -I../3rdparty/md4 -Itmp/moc/debug_shared animati
on/qabstractanimation.h -o tmp/moc/debug_shared/moc_qabstractanimation.cpp
/opt/toolchains/arm-2011.09/bin/arm-none-linux-gnueabi-g++ -c -pipe -g —
Wall -W -D_REENTRANT -fPIC -DQT_SHARED -DBCM_PI -DQT_BUILD_CORE_LIB -DQT_NO_USIN
G_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COMPAT -DQT_
USE_QSTRINGBUILDER -DELF_INTERPRETER=\»\» -DQLIBRARYINFO_EPOCROOT -DHB_EXPORT=Q_
CORE_EXPORT -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HA
VE_SSE2 -I../../mkspecs/linux-rasp-pi-g++ -I. -I../../include -I/mnt/rasp-pi-roo
tfs/opt/vc/include -I/mnt/rasp-pi-rootfs/usr/include -I/opt/dev/src/qt-platform-
mkspecs/5.0/linux-rasp-pi-g++/header-taint -I../../include/QtCore -Itmp\rcc\debu
g_shared -Iglobal -I../../tools/shared -I../3rdparty/zlib -I../3rdparty/harfbuzz
/src -I../3rdparty/md5 -I../3rdparty/md4 -Itmp/moc/debug_shared -o tmp/obj/debug
_shared/qabstractanimation.o animation/qabstractanimation.cpp
Системе не удается найти указанный путь.
NMAKE : fatal error U1077: » : return code ‘0x1’
Stop.
NMAKE : fatal error U1077: ‘cd’ : return code ‘0x2’
Stop.
Полезло куда то в /opt/toolchains/arm-2011.09/bin/arm-none-linux-gnueabi-g++. На моем компьютере таких папок вообще нет. Кхм. Откуда он их взял?
Я так понимаю это и должен быть тулчейн, вот только откуда блин его взять? тулчейн для raspbian не содержит таких файлов
В связи с этой вирусной хренью у меня сейчас высвободилось какое-то количество свободного времени, которое я решил посвятить ревизии текущих проектов и документации. Гайд по сабж, написанный моим сотрудником полгода назад, безнадежно устарел за это время, поэтому решил его освежить. Ну а бонусом, выкинуть это в паблик — не срачами же едиными. Надеюсь, кому-то эта информация окажется полезной и через гугл этот гайд спасет ему какое-то количество времени.
Собирать будем на примере ARM linux, i-mx6. Host — ubuntu linux. Информацию я попытался предоставить таким образом, чтобы объяснить суть процесса, а не сделать очередной обезьяний рецепт для копирования. Местами ну уж очень для новичков — но лучше пусть обзор будет полным, чем потом тридцать раз дополнять.
1. Тулчейн
Для Qt необходимы одновременно C компилятор и С++ компилятор. К счастью, наконец это не приходится делать сбором из исходников и конфигурирования, либо использовать третьесортные репозитории. Все уже завезли в apt:
apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
gcc — Си компилятор, g++ — соответственно С++
linux-gnu — обозначает сборку для выполнимых файлов в среде GNU/Linux. Для baremetall нужны пакеты с корнем none
hf — hardfloat. Скорее всего ваш application процессор будет именно таким.
В принципе все. Для windows пользователей необходимо
страдать
скачать/собрать аналогичный пакет на базе mingw.
2. Сборка Qt
Для кросс-компиляции исходники Qt необходимо пересобрать под целевую платформу.
Брать можно отсюда: https://download.qt.io/official_releases/qt/. Дальше выбираем ветку, каталог single. На момент написания последняя ревизия 5.14.2. Прямая ссылка.
Самый сложный этап в сборке это конфигурирование. В общем виде основные параметры конфигурирования выглядят так:
./configure <тип линковки> <рецепт> <настройки рецепта> <каталог установки> <лицензия> <тип сборки> <что пропустить> <тонкая настройка>
тип линковки — shared, static. Про статическую линковку и авторские права еще в двух словах чуть ниже.
рецепт. В общем случае это набор базовых правил для кросс-компиляции. Если используется ключевое слово xplatform, рецепты находятся по адресу /qtbase/mkspecs. Для device — /qtbase/mkspecs/devices. Чем еще отличаются эти два ключевых слова, я так и не понял.
настройки рецепта. Фактически это передача определенных DEFINE в рецепт. В большинстве случаев кросс-компиляции потребуется, как минимум, передать префикс имени компилятора — чтобы одновременно были доступны компиляторы под разные платформы, в системе кросс-компиляторам назначается дополнительный префикс. Например, наш компилятор под arm будет не просто gcc, a arm-linux-gnueabihf-gcc. Задается через device_option (даже если рецепт указан через xplatform). Соответственно, необходимо передать -device-option CROSS_COMPILE=arm-linux-g
каталог установки. Куда будет производиться установка. Некоторые говорят, что необходимо монтировать файловую систему удаленной машины в этот каталог. По моему мнению этот шаг лишний — монтирование вообще никак не влияло на выходные файлы и компиляцию. Так что просто выходной каталог. При динамической линковке выходные библиотеки (/usr/local/) необходимо скопировать на целевую машину. Если указано device, то задается через ключевое слово sysroot. А если xplatform — prefix. Это невозможно понять, нужно просто запомнить.
лицензия. Тут все просто — если вы купили коммерческую лицензию, у вас есть саппорт и данный гайд вам не нужен. Во всех остальных случаях указывайте -opensource -confirm-license
тип сборки — release, debug, debug-and-release. Я обычно ставлю только релиз.
что пропустить. Задается двумя ключевыми словами — nomake, варианты: libs, examples, tools, tests. И через skip: список пакетов, начинающихся с qt* в каталоге исходников. Я всегда выкидываю исходники и тесты.
тонкая настройка. Задается включением через -feature или выключение через -no-feature. Список с описанием можно получить через -list-features. Если собирается без этого, я не рекомендую лишний раз сюда лезть. Проблемы могут вылезти совершенно в другом месте.
Это базово, что необходимо знать про параметры конфигурирования. Полный список параметров доступен по —help. Но местами все не так просто, как может показаться — для конкретного пакета под определенную архитектуру может быть совершенно нетривиальный список зависимостей, который задается либо через features, либо через device-option. В более тяжелых случаях придется патчить исходники и/или править рецепты, предварительно перелопатив тонны кода. Я предпочитаю просто выкинуть пакет, если от него нет необходимости прямо сейчас.
Итого, рабочий набор параметров для сборки qt под arm для версии 5.14.2:
./configure -static -no-opengl -device linux-imx6-g++ -device-option CROSS_COMPILE=arm-linux-gnueabihf- -sysroot ~/opt/qt-cross/rootfs-arm -opensource -confirm-license -release -qt-sqlite -nomake examples -nomake tests -skip serialport -skip serialbus -skip quick3d -skip location
Дальше стандартно:
make && make install
Чтобы собиралось быстрее, рекомендую запускать make в несколько потоков. Общую рекомендацию где-то видел как кол-во ядер * 2 + 1. Т.е. для 6-ядерного процессора с гипертредингом должно быть:
make -j25
Один нюанс. Я натыкался на сообщения, что некоторые ревизии Qt валились при сборке в несколько потоков. Текущая ревизия собирается нормально, но…
Все. Можно собирать бинари. Если не используете qt-creator, следующий раздел можно не читать.
Логично было бы после этого собрать версию под windows, чтобы лишний раз не запускать богомерзкую для клиентских релизов. Авотхуй. Сборка безнадежно поломана в 5.14.2. Я уже и i686 и x64 собирал, и свои рецепты писал — бесполезно. Три совершенно разных ошибки. В одних случаях там что-то в libatomic поломали, в других даже внутренняя ошибка компилятора. Потратил кучу времени, не взлетело. А возможно и руки кривые. Забил.
3. Деплой
Данный раздел посвящен развертыванию приложений с использованием Qt Creator.
Открываем проект, Инструменты->Параметры.
Устройства
Добавить->Обычное Linux устройство. Для развертывания на устройстве нужны ssh, rsync.
Комплекты
Прописать компилятор для C/C++
Указать в комплектах путь к собранному qmake
И все вместе:
Чтобы Qt Creator понимал, какие файлы куда класть, необходимо это указать в .pro файле:
target.path += /home/ubuntu
INSTALLS += target
Т.е. кладем выходной бинарь в каталог /home/ubuntu на целевом устройстве. В проектах добавляется целевое устройство, после этого появляется пункт «Развернуть».
Теперь можно собирать кросс-платформенно и развертывать двумя кликами.
4. О статической линковке
В заключении о сабже в комлекте с LGPL. Очень долгое время я считал, что LGPL разрешает только динамическую линковку. Однако это не так и есть официальные разъяснения от FSF:
(1) Если вы статически компонуете с библиотекой под LGPL, вы должны предоставить свое приложение в формате объектного кода (не обязательно исходного текста), с тем чтобы у пользователя была возможность изменить библиотеку и перекомпоновать приложение.
Т.е. по запросу будете обязаны предоставить объектный файл, а не исходный код. Уточню, что запросить объектник у вас может исключительно покупатель вашего продукта, а не абы кто.
Почему я заострил на это внимание? Во-первых у меня возникли проблемы с компиляцией Qt с динамической линковкой — драйверы sql просто отказались подгружаться. Аналогичная проблема (но с чем-то другим, сейчас уже никто не помнит) была у моих ребят, когда они писали предыдущий гайд. Во-вторых, при статической линковке, бинарь будет в разы меньше, чем полный набор библиотек. Для embedded устройств это может быть критично.
Есть один нюанс. Если вдруг каким-то образом в сборке окажется GPL библиотека, придется предоставить весь исходный код.