Qt for BeagleBone BlackВведение

На сегодняшний день в сети есть достаточно много мануалов сборки qt4.8 для Raspberry PI или BeagleBone Black, но они уже безвозвратно устарели (изменились опции для ./configure).

В сети уже есть несколько инструкций как собирать qt5.2 и qt5.5, но без дополнительных тайных знаний вы можете потратить много времени и нервов, так ничего и не добившись.

 

За основу я взял статью Simon Stürz : Crosscompile Qt 5.2.1 for the Beaglebone Black и скрипт автоматической сборки, делающий всю работу за вас.

Здесь же не только перевод этой статьи, но и важные ньюансы и пояснения, позволяющие вам не тратить много времени на набивании шишек.

Ставим линукс

Есть куча примеров кросс-компиляции под windows, но если вы хотите сэкономить себе время и нервы, используйте Linux. Позже, когда вы разберётесь как всё работает на линуксе, можно уже будет попробовать собрать и под виндой.

Ставить линукс второй операционной системой вовсе не обязательно, вы можете запустить его на виртуальной машине, например при помощи VirtualBox. Такой способ будет даже удобнее: пока идёт сборка qt можно спокойно работать на основной машине.

Ставим Ubuntu 14.04. Если вы ставите Linux на виртуалку, то настоятельно рекомендую именно этот дистрибутив или другой хорошо распространнённый. Посколько в других дистрибутивах могут отличаться названия пакетов.

Подготовка rootfs

Для успешной сборки нам понадобится образ файловой системы с вашего работающего Beaglebone. Это нужно, чтобы слинковаться с конкретными библиотеками, установленными на вашу систему.

Важно: для образа вашей файловой системы используйте SD-карту. Файловую систему на карте памяти намного проще скопировать на компьютер. Делается это через обычный кардридер. Сложнее скопировать файловую систему на внутренней памяти BeagleBone: для этого придётся разбираться с копирование файлов по SSH.

В качестве дистрибутива для BeagleBone я использую Debian 7.9.

Установка обновлений (выполняем на BeagleBone)

Для начала, установим системные обновления:

$ sudo apt-get update
$ sudo apt-get upgrade

Установка зависимостей

Все библиотеки и include-файлы, необходимые для сборки Qt будут браться не с вашего компьютера, а с rootfs BeagleBone. Поэтому, необходимо поставить туда все необходимые пакеты.

Основные зависимости:

$ sudo apt-get install libc6-dev

Зависимости для libxcb:

$ sudo apt-get install "^libxcb.*" libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev

Зависимости для QtMultimedia:

$ sudo apt-get install libasound2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev

Зависимости для QtWebEngine:

$ sudo apt-get install libcap-dev libbz2-dev libgcrypt11-dev libpci-dev libnss3-dev build-essential libxcursor-dev libxcomposite-dev libxdamage-dev libxrandr-dev libdrm-dev libfontconfig1-dev libxtst-dev libasound2-dev gperf libcups2-dev libpulse-dev libudev-dev libssl-dev flex bison ruby

Зависимости для QtConnectivity (поддержка Bluetooth):

$ sudo apt-get install bluez libbluetooth-dev bluetooth bluez-tools

Работы с шиной I2C (если вы не знаете что это такое, то скорее всего вам это не нужно):

$ sudo apt-get install i2c-tools libi2c-dev

Подготовка директории на диске

Прежде чем копировать образ файловой системы с BeagleBone на компьютер, нужно подготовить директорию.

Важно: директория на вашей TARGET-машине будет в точности соответствовать директории на HOST-машине (BeagleBone). Т.е если вы решите производить сборку в /home/vasya/Projects/build. То все пути будут завязаны именно на эту директорию. Настоятельно рекомендуется указывать пути не зависящие от конкретного пользователя. Например /opt/qt-beaglebone/.

Создаём директорию под рутом (т.к. обычный пользователь не может писать в корень диска) и меняем владельца на текущего пользователя:

$ sudo mkdir /opt/qt-beaglebone/
$ sudo chown $USER /opt/qt-beaglebone/

Создание снимка rootfs

Извлекаем карту памяти из BeagleBone, вставляем её в кард-ридер своего компьютера.

Затем монтируем файловую систему sd-карты (под Ubuntu файловая система монтируется сама) и заходим в корень смонтированной файловой системы.

Там выполняем:

$ sudo tar cpjfv /opt/qt-beaglebone/rootfs.tar.bz2 ./
$ sudo chown $USER /opt/qt-beaglebone/rootfs.tar.bz2

 

Сборка QT для кросс-компиляции

Подготовка машины для сборки

Ставим необходимые пакеты:

$ sudo apt-get install lib32z1-dev

Скрипт сборки Qt

Можно было бы самим скачать пакет qt-everywhere-opensource. Наложить на него патч для поддержки BeagleBone и компилятора gcc-linaro-arm-linux-gnueabihf, но есть уже готовый скрипт от товарища Simon Stürz. С 2015 года пути немного поменялись и скрипт безнадёжно устарел. Пришлось его немного допилить. Новый скрипт можно взять здесь.
Если у вас есть rootfs со всеми необходимыми библиотеками, то остальное скрипт сделает за вас. Нужно только его скачать и запустить:

$ cd /opt/qt-beaglebone/
$ wget http://guh.guru/downloads/scripts/crosscompile-Qt_5.2.1-beaglebone-black.sh
$ chmod +x crosscompile-Qt_5.2.1-beaglebone-black.sh
$ ./crosscompile-Qt_5.2.1-beaglebone-black.sh

Скрипт распакует архив с rootfs (лучше не удалять исходный архив. Если что-то пойдёт не так вы всегда сможете вернутся к исходной версии). Далее скрипт скачает дистрибутив Qt-5.2.1, компилятор и начнёт сборку.

Собранный Qt для ARM

Собранный Qt будет лежать на распакованном образе rootfs в директории /opt/qt-beaglebone/. Полный путь на вашей HOST-машине будет: /opt/qt-beaglebone/rootfs/opt/qt-beaglebone/Qt-5.2.1/.

qmake для кросс-компиляции

qmake для кросс-компиляции будет находиться здесь: /opt/qt-beaglebone/Qt-5.2.1

Компилятор будет находиться здесь: /opt/qt-beaglebone/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin

Кросс-компиляция Qt-приложений под ARM

Кросс компиляции Qt-приложений под ARM будет посвещена следующая статья.

Возможные проблемы

Проблемы при сборке Qt для BeagleBone

1. gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin/arm-linux-gnueabihf-g++: error while loading shared libraries: libstdc++.so.6

Решение: скорее всего не хватает пакетов на вашей сборочной системе:

sudo apt-get install libc6-i386 lib32z1 lib32stdc++6

2. arm-linux-gnueabihf/libz.a: error adding symbols: Bad value

Вместо libz.so тут может быть любая библиотека. Проблема в то, что libz.so не найден на вашей файловой системе. И компилятор пытается использовать вместо динамической либы libz.so статическую libz.a, которой тоже нет на вашей rootfs. Решение: идём в директорию rootfs и создаём libz.so как ссылку на существующую библиотеку (в моём случае это libz.so.1.2.7).

$cd /opt/qt-beaglebone/rootfs/usr/lib/arm-linux-gnueabihf/
$ln -s libz.so.1.2.7 libz.so

Скорее всего тоже самое придётся проделать и для других библиотек. Мне пришлось повторить это действие для libm.so, libdl.so.  Притом в директориях /lib/arm-linux-gnueabihf и /usr/lib/arm-linux-gnueabihf

Внимание! Проверять нужно не только наличие библиотеки *.so но и куда ссылается символическая ссылка.

Например:

$ cd /opt/qt-beaglebone/rootfs/usr/lib/arm-linux-gnueabihf/
$ ls -l |grep libdl

выводит

-rw-r--r-- 1 root root     9022 фев 12  2016 libdl.a
lrwxrwxrwx 1 root root       35 фев 12  2016 libdl.so -> /lib/arm-linux-gnueabihf/libdl.so.2

Т.е. символическая ссылка с абсолютными путями и ссылается не на библиотеку для Beaglebone, а на библиотеку для x86 процессора, на котором мы выполняем сборку.

Исправляем:

$ cd /opt/qt-beaglebone/rootfs/usr/lib/arm-linux-gnueabihf/
$ rm -rf libdl.so
$ ln -s ../../../lib/arm-linux-gnueabihf/libdl-2.13.so libdl.so

3. crosscompile-Qt_5.2.1-beaglebone-black.sh: /opt/qt-beaglebone/Qt-5.2.1/bin/qmake: not found

Найдя директорию Qt-5.2.1, скрипт считает, что всё уже собрано, и пытается запустить qmake, который не собрался из-за ошибки. Самый простой способ будет - удалить директорию Qt-5.2.1.

4. undefined reference to `clock_gettime`

Проблема линковки в librt.so. Для неё также нужно создать символическую ссылку как для libz.so, обозначенной во второй проблеме.

5.  undefined reference to `__dlopen'

Та же самая проблема, что и проблема 2: /usr/lib/arm-linux-gnueabihf/libdl.so отсутствует, либо символическая ссылка ведёт не туда.
Исправляем:

$ cd /opt/qt-beaglebone/rootfs/usr/lib/arm-linux-gnueabihf/
$ rm -rf libdl.so
$ ln -s ../../../lib/arm-linux-gnueabihf/libdl-2.13.so

То же самое нужно сделать и для libm.so.

Если и это не помогает, то удаляем/переименовываем статическую библиотеку, чтобы компилятор начал использовать динамическую:

$ cd /opt/qt-beaglebone/rootfs/usr/lib/arm-linux-gnueabihf/
$ sudo mv libdl.a old-libdl.a

 

Добавить комментарий


Поиск