Pull to refresh

Qt Creator 2.3 и Remote Linux Deploy

Reading time 7 min
Views 14K
В очередной раз на хабре осталась незамеченной новость, которая пробежала в блоге Qt Labs и известила о выходе Qt Creator 2.3. Если вскользь просмотреть список изменений, то как обычно можно увидеть кучу прикольных плюшек, одна из которых заинтересовала меня неимоверно. А именно — развёртывание и отладка приложения на удалённой Linux-машине, при помощи ssh, прямиком из среды разработки.

Почему мне это было интересно? Да потому что:
1) У нас в конторе есть arm-железяка, для которой потихонечку пилится своя прошивка на базе Qt/Embedded+Linux.
2) Кросс-компиляция, развёртывение и отладка очередной версии какой-либо из программ написанных с использованием Qt, как не сложно догадаться доставляет неимоверное удовольствие и сексуальное удовлетворение в виду необходимости использовать
кучу самопальных скриптов типа build.sh, deploy.sh и прочее.
3) Продуктивность понижается (а вот уровень раздражения повышается) и я даже начинал копаться в исходниках android-lighthouse чтобы стырить оттуда методику развёртывния пакетов на виртуальный Android-телефон… Слава богу не успел ничего написать).

Что же нам предлагается? Как известно ранее в Qt Creator-е уже существовали средства для разворачивания приложений на Symbian (через USB-MicroUSB) и для Maemo (через ssh). Видимо в данной версии разработчики решили довести задумку до ума и засчёт унификации средства Maemo-деплоя позволить разворачивать приложения и на обычных Linux-машинах.

В нашем распоряжении появились пара новых вкладок в настройках:
  • Интсрументарий — здесь можно указать компилятор. Конечно же как простой, так и кросс-компилятор.
  • Linux Devices — здесь указываются настройки развёртки собранного приложения на удалённой машине

Поехали?

Изначальные условия:
Основная Linux-машина, на которой стоит среда разработки Qt Creator 2.3 Beta, есть gdb и присутствуют исходники необходимой программы.
Удалённое устройство с Linux, доступом по ssh и установленным gdbserver.
Кросс-тулчейн для сборки (со скомпилированной Qt/Embedded конечно) и кросс-компилятор. Которые, к примеру, как в моём случае лежат ни разу не на той же машине где и исходники, а совсем даже на соседнем сервере). Что задачи нифига не облегчает… Но тем не менее буду объяснять именно на этом примере. В качестве инструментария используется buildroot, в качестве набора компиляторов — codesourcery. Платформа — ARM (armv7a).

Итак, первое что стоит сделать, это спросить у qmake относящегося к кросс-скомпилированной версии Qt кое о чём… А именно, заходим на машинку, на которой у нас лежат средства кросс-сборки и выполняем примерно следующее:
# /root/openaos/br11_glibc_building/output/staging/usr/bin/qmake -v
QMake version 2.01a
Using Qt version 4.7.1 in /root/openaos/br11_glibc_building/output/staging/usr/lib

Это как бы намекает нам о местоположении нашей библиотеки. На всякий случай заглядываем в файлик
/root/openaos/br11_glibc_building/output/staging/usr/mkspecs/qws/linux-arm-g++/qmake.conf

Чтобы убедиться что тулчейн там указан вполне правильный:
QMAKE_LFLAGS = -L/root/openaos/br11_glibc_building/output/staging/lib -L/root/openaos/br11_glibc_building/output/staging/usr/lib
QMAKE_CXXFLAGS = --sysroot=/root/openaos/br11_glibc_building/output/staging -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Os  -mtune=cortex-a8 -march=armv7-a -mab$
QMAKE_CFLAGS = --sysroot=/root/openaos/br11_glibc_building/output/staging -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Os  -mtune=cortex-a8 -march=armv7-a -mabi=$
QMAKE_STRIP = /root/codesourcery/arm-2010.09/bin/arm-none-linux-gnueabi-strip
QMAKE_RANLIB = /root/codesourcery/arm-2010.09/bin/arm-none-linux-gnueabi-ranlib
QMAKE_OBJCOPY = /root/codesourcery/arm-2010.09/bin/arm-none-linux-gnueabi-objcopy
QMAKE_AR = /root/codesourcery/arm-2010.09/bin/arm-none-linux-gnueabi-ar cqs
QMAKE_LINK_SHLIB = /root/codesourcery/arm-2010.09/bin/arm-none-linux-gnueabi-g++ --sysroot=/root/openaos/br11_glibc_building/output/staging
QMAKE_LINK = /root/codesourcery/arm-2010.09/bin/arm-none-linux-gnueabi-g++ --sysroot=/root/openaos/br11_glibc_building/output/staging
QMAKE_CXX = /root/codesourcery/arm-2010.09/bin/arm-none-linux-gnueabi-g++
QMAKE_CC = /root/codesourcery/arm-2010.09/bin/arm-none-linux-gnueabi-gcc

Следующий этап предварительной подготовки — смонтировать все необходимые каталоги по sshfs так чтобы тулчейну и прочим казалось что они никуда и не монтировались, а живут вполне себе припеваючи на той же машине где и должны находиться. Как несложно догадаться, смонтировать придётся 2 каталога: /root/codesourcery/ и /root/openaos/br11_glibc_building/

Делаем…
$ sudo chmod 777 /root 
$ cd /root
$ mkdir oabroot
$ sshfs root@openaos-build.lan.arta.kz:/ oabroot/
$ ln -s oabroot/root/openaos/ ./
$ ln -s oabroot/root/codesourcery/ ./
$ ls -l
итого 4
lrwxrwxrwx 1 kafeg kafeg   26 2011-07-22 16:10 codesourcery -> oabroot/root/codesourcery/
drwxr-xr-x 1 root  root  4096 2011-07-13 08:44 oabroot
lrwxrwxrwx 1 kafeg kafeg   21 2011-07-22 16:10 openaos -> oabroot/root/openaos/

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

И тем не менее, продолжим. По сути, в данный момент на нашей хост машине уже доступен сборочный инструментарий и если выполнить что-то вроде ls /root/openaos/br11_glibc_building/output/staging/usr/lib, можно получить не сообщение об отсутствующем каталоге, а вполне адекватную, хоть и заторможенную реакцию ls, выводящего сотни файлов. Порой даже кажется, на кой хрен всё это нужно… =)

Ладно. Запускаем креатор и переходим в настройки. Первым делом, стоит указать путь до новоиспечённой Qt (что-то habrastorage на этом моменте помер, что меня поставило в ступор, но где наша не пропадала...):
image

По картинке ясно, что среда разработки нашла саму библиотеку и прочую фигню, но весьма расстроилась от того что не знает чем же всё это компилировать и где брать тулчейн. Объясним…

Для этого переходим в раздел «Инструментарии», добавляем новый компилятор типа GCC и заполняем необходимые поля — путь к компилятору и отладчику:
image

Вновь возвращаемся к разделу Qt и вуаля, сообщения об отсутствующем тулчейне пропали:
image

Последний штрих в диалоге настроек — надо бы добавить устройство, на котором мы хотим разворачивать наше приложеньице… нет ничего проще, переходим к разделу Linux Devices, жмякаем по кнопке «Добавить» -> «Generic Linux Device» -> заполняем поля мастера и завершаем настройку. Тут же появится окошко с тестом соединения.
image

Что примечательно, если Вам не хочется иметь на удалённо машине пароль, можно сразу из интерфейса настройки соединения сгенерировать пару ssh-ключей и даже задеплоить публичный ключ на устройство. А затем преспокойненько удалить пароль или забыть пароль… Правда один баг здесь всё же присутствует. Записан публичный ключик будет в <каталог пользователя>/.ssh/authorized_keys и следовательно авторизация по ключам будет работать, если на устройстве установлен полноценный ssh-сервер, а не какой-нибудь dropbear к примеру. Стоит также обратить внимание на пункт «Тип устройства», который подсказывает, что ничто не мешает нам запустить наш удалённый Linux на виртуальной машине. Хотя конечно это и так понятно было…

Жмякаем Ок и закрываем диалог настроек. Неужто всё? Фиг =)

Открываем проект, относящийся к железке, переходим на вкладку «Проекты» и меняем конфигурацию сборки на необходимую нам.
image

Как видно при смене конфигурации автоматически была выбрана требуемая версия Qt и необходимый toolchain. Правда здесь нас всё же поджидает второй баг — какой бы профиль Qt не был выбран, всё равно по умолчанию параметр -spec будет равен linux-g++. а нам необходим "-spec qws/linux-arm-g++", что можно поправить вписав его в поле «Дополнительные параметры», этапа сборки qmake. Если этого не сделать, конечно же будет сыпаться куча страшных ошибок:
...
qatomic_arm.h:131: Error: no such instruction: `swpb %dl,%al,[%ebx]'
...


В настройках запуска необходимо также внести изменения — добавить новую конфигурацию «Build Tarball and Install to Linux Host», в появившемся окне выбрать необходимые подпроекты, которые хотелось бы задеплоить, согласиться, пошариться по списку файлов для установки и если необходимо что-то поменять… Кстати, если хочется изменить пути установки неких файлов, то всё конфигурируется в файле проекта директивами типа:
unix:!symbian:!maemo5:isEmpty(MEEGO_VERSION_MAJOR) {
    target.path = /opt/authorize/bin
    INSTALLS += target
}

Далее чуть ниже добавляем новый вариант запуска приложения — «имя_бинарника (remote)», дописать параметр к примеру "-qws", так как всё-же это приложение для Embedded версии библиотеки. Получается что-то вроде:
image

Уже неплохо… Что дальше? Дальше — попробуем собрать! Редактор -> Сборка (Esc -> Ctrl+R). И ждём пока наше приложение соберётся. В моём случае это самая продолжительная процедура…

Попили кофе? А теперь взгляните ка на вашу железку… Не появилось ли там окошко вашего приложения? Если всё собралось правильно, то уже должно бы…

Вот только… Если в Вашем проекте помимо собственно приложений существуют так же и разделяемые библиотеки, то на этапе сборки tar-архива для заливки его на устройство может появитсья ошибка типа:
Creating package file ...
Error reading file '/root/oabroot/*/libqmlgestureareaplugin.so.1': No such file or directory.
Возникла ошибка при сборке проекта artagui (цель: Desktop)
Во время выполнения сборки на этапе «Create tarball»

Это конечно легко исправить, но всё же не очень то приятно получать подобные сообщения об ошибках в самом конце сборки приложения. Придётся сделать что-то вроде для всех разделяемых библиотек, входящих в проект:
$ ln -s /root/oabroot/*/libqmlgestureareaplugin.so /root/oabroot/*/libqmlgestureareaplugin.so.1
$ ln -s /root/oabroot/*/libqmlgestureareaplugin.so /root/oabroot/*/libqmlgestureareaplugin.so.1.0
$ ln -s /root/oabroot/*/libqmlgestureareaplugin.so /root/oabroot/*/libqmlgestureareaplugin.so.1.0.0

И наконец после окончательных исправлений, можно лицезреть окончательный лог среды разработки, который уже так и кричит о своей готовности:
image

А лог запуска приложения радостно вопит:
Killing remote process(es)...
Starting remote process ...
Remote process started.
Killing remote process(es)...


Собственно… Данный способ разворачивания приложений можно использовать не только для кросс-сборки или удалённого запуска, но и просто для автоматической сборки tar-архивов с дистрибутивами Ваших приложений. Для этого достаточно указать в качестве машины для развёртки IP хост-машинки и впилить необходимые инструкции установки в .pro файл. Это повышает удобство разработки к примеру QML-приложений, в которых всегда есть куча мелких файлов которые необходимо таскать за собой по пятам… А так, можно наконец не городить огород и для сборки дистрибутивов под linux использовать те же самые INSTALL-параметры из .pro файла, которые используются и при сборке дистрибутивов для Symbian.

Вот такая фича, которая в очередной раз показывает что:
а) разработка ПО может быть простой
б) Разработчики Qt думают в первую очередь о своих пользователях (то бишь разработчиках, пользующих их продукт) и делают всё для повышения их продуктивности и привлекательности библиотеки в целом.

Благодарю, надеюсь кому-либо окажется полезным.
Tags:
Hubs:
+38
Comments 22
Comments Comments 22

Articles