MBR (mbr) wrote,
MBR
mbr

Category:

Кросс-компиляция в Qt

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

Собирать будем на примере 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-gnueabihf-.

каталог установки. Куда будет производиться установка. Некоторые говорят, что необходимо монтировать файловую систему удаленной машины в этот каталог. По моему мнению этот шаг лишний - монтирование вообще никак не влияло на выходные файлы и компиляцию. Так что просто выходной каталог. При динамической линковке выходные библиотеки (/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.
howto0

Комплекты

Прописать компилятор для C/C++
howto1

Указать в комплектах путь к собранному qmake
howto2

И все вместе:
howto3

Чтобы Qt Creator понимал, какие файлы куда класть, необходимо это указать в .pro файле:

target.path += /home/ubuntu

INSTALLS += target


Т.е. кладем выходной бинарь в каталог /home/ubuntu на целевом устройстве. В проектах добавляется целевое устройство, после этого появляется пункт "Развернуть".

Теперь можно собирать кросс-платформенно и развертывать двумя кликами.

4. О статической линковке

В заключении о сабже в комлекте с LGPL. Очень долгое время я считал, что LGPL разрешает только динамическую линковку. Однако это не так и есть официальные разъяснения от FSF:

(1) Если вы статически компонуете с библиотекой под LGPL, вы должны предоставить свое приложение в формате объектного кода (не обязательно исходного текста), с тем чтобы у пользователя была возможность изменить библиотеку и перекомпоновать приложение.

Т.е. по запросу будете обязаны предоставить объектный файл, а не исходный код. Уточню, что запросить объектник у вас может исключительно покупатель вашего продукта, а не абы кто.

Почему я заострил на это внимание? Во-первых у меня возникли проблемы с компиляцией Qt с динамической линковкой - драйверы sql просто отказались подгружаться. Аналогичная проблема (но с чем-то другим, сейчас уже никто не помнит) была у моих ребят, когда они писали предыдущий гайд. Во-вторых, при статической линковке, бинарь будет в разы меньше, чем полный набор библиотек. Для embedded устройств это может быть критично.

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

Tags: howto, it, linux
Subscribe

  • Победил битрикс

    Раньше рассказывал, как мы пытаемся битрикс внедрить. Сначала просто дал задачу вебщику подергать странички и собрать отчет по линкам. Ад. Там…

  • Советский инженер - это звучит гордо

    Порадовался с последнего стеба vladimir_akinin над программистами. Однако в комменты выползло какое-то количество старых пердунов,…

  • Сезон 2021

    Весна началась, а значит пора новой стройки Делать пристройку в этот раз решил полностью по платформе, дабы не переломали все ноги, выходя из…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 17 comments

  • Победил битрикс

    Раньше рассказывал, как мы пытаемся битрикс внедрить. Сначала просто дал задачу вебщику подергать странички и собрать отчет по линкам. Ад. Там…

  • Советский инженер - это звучит гордо

    Порадовался с последнего стеба vladimir_akinin над программистами. Однако в комменты выползло какое-то количество старых пердунов,…

  • Сезон 2021

    Весна началась, а значит пора новой стройки Делать пристройку в этот раз решил полностью по платформе, дабы не переломали все ноги, выходя из…