На своем компьютере для разработок нажимаете Ctrl+R (Run (Выполнить)) в QtCreator, чтобы создать и запустить ваше приложение Qt. Если вы хотите запустить приложение во встроенной системе, то вы должны выполнить четыре задачи:
• Создаете кросс-приложение Qt для целевой встроенной системы в контейнере Docker.
• Останавливаете приложение в целевой системе.
• Копируете приложение с ПК разработчика в целевую систему с помощью scp.
• Запускаете приложение в целевой системе.
Хотели бы вы нажать Ctrl+R в QtCreator и заставить QtCreator выполнить для вас четыре вышеуказанных шага? Конечно, хотели! В этой статье будет рассказано как это сделать. Запуск приложения во встроенной системе будет аналогичен запуску приложения на ПК.
Настройка (Setup)
Промышленные терминалы (например, компьютерные дисплеи) запускают приложения для мониторинга и управления машинами. Они часто работают на процессорах Intel или AMD с архитектурой x86_64. Ubuntu - довольно естественный выбор для операционной системы. Пользовательский интерфейс Ubuntu на рабочем столе может быть отключен, поскольку терминал запускает только основное приложение, и может быть одним или двумя вспомогательными приложениями.
Настроить среду разработки для промышленных терминалов довольно просто. Ваш ПК для разработки работает под управлением какой-то версии Ubuntu (у разработчика установлен: Ubuntu 16.04). Целевая система работает на другой версии Ubuntu (у разработчика: Ubuntu 18.04). Кросс-сборочная среда в контейнере Docker - это не что иное, как среда Ubuntu 18.04 со всеми пакетами, установленными для сборки библиотек Qt и приложения.
Вам даже не нужен изготовленный на заказ терминал. Вам нужны только два ПК с Linux, которые подключены через (W)LAN и могут обмениваться данными через OpenSSH друг с другом.
Если целевая система работает на ARM SoC, настройка среды кросс-сборки в контейнере Docker будет немного сложнее. Вы должны собрать Qt SDK (например, путем создания meta-toolchain-qt5 цели Yocto (target) ) и установить Qt SDK в контейнер Docker. Контейнер скрывает среду кросс-сборки от QtCreator. QtCreator не знает, вызывает ли контейнер кросс-компилятор для целей ARM или собственный компилятор для целей Intel.
Если вы хотите следовать примеру проекта или собственному проекту, должны быть выполнены следующие предварительные условия.
Вы устанавливаете Docker на свой компьютер для разработки, как описано здесь.
Вы создаете рабочий каталог (для разработчика: /public/Work ) на своем ПК для разработки. Вы клонируете репозиторий с примером проекта или вашего проекта в рабочий каталог.
$ cd /public/Work $ git clone https://github.com/bstubert/qtcreator-with-docker.git $ cd qtcreator-with-docker
Каталог проекта содержит Dockerfile. Установите WORKDIR в последней строке вашего рабочего каталога. Это важно, как вы увидите в следующих разделах. Для разработчика последняя строка выглядит так:
WORKDIR /public/Work
Затем вы следуете этому описанию для создания образа Docker qt-ubuntu-18.04-ryzen и используете этот образ для сборки перемещаемых библиотек Qt (Qt 5.14 или новее). Сборка Qt дает вам tarball qt-5.14.1-ubuntu-18.04-ryzen.tgz , который вы распаковываете в рабочем каталоге.
$ cd /public/Work $ tar xf /path/to/qt-5.14.1-ubuntu-18.04-ryzen.tgz
Распаковка устанавливает библиотеки Qt в каталог /public/Work/qt-5.14.1 .
У вас есть работающее соединение OpenSSH между вашим ПК и целевой системой. Аутентификация по паролю работает нормально.
Docker Wrapper для CMake
Когда вы собираете и устанавливаете приложение Qt, QtCreator вызывает CMake:
• создать Makefiles (Make-файлы). Это вызывает:
cmake /public/Work/qtcreator-with-docker '-GCodeBlocks - Unix Makefiles
во временном каталоге, например
/tmp/QtCreator-jZQYdh/qtc-cmake-caIYzSxO
.
• скомпилировать и связать приложение Qt. Это вызывает:
cmake --build . --target all
в каталоге сборки, например
/public/Work/build-RelocatableQt-Qt_5_14_1-Debug
.
• установить приложение Qt и его вспомогательные файлы. Это вызывает:
cmake --build . --target install
в каталоге сборки.
Идея состоит в том, чтобы вызвать CMake внутри контейнера Docker. Прежде чем QtCreator вызывает CMake, он переключается в определенный каталог на компьютере разработчика или хосте. Этот каталог должен быть передан контейнеру, чтобы CMake можно было вызвать в нужном месте внутри контейнера. Сценарий оболочки CMake dr-cmake делает следующее.
#!/bin/bash docker run --rm -v /public/Work:/public/Work -v/tmp:/tmp -w $(pwd) qt-ubuntu-18.04-ryzen cmake $@
Опции -v /public/Work:/public/Work и -v/tmp:/tmp отражают дерево рабочего и временного каталога от хоста до контейнера. Опция w $(pwd) передает каталог хоста, где QtCreator вызывает CMake, как текущий рабочий каталог в контейнер Docker. Docker запускает cmake с аргументами $@, переданными в скрипт dr-cmak e.
Сценарий dr-cmake переводит действия QtCreator на хост-компьютер в те же действия в контейнере Docker. Этот перевод работает только потому, что хост-компьютер и контейнер Docker имеют одинаковую структуру каталогов.
Скопируйте скрипт-обертку dr-cmake в каталог, содержащийся в $PATH (e.g. ~/bin) , и убедитесь, что скрипт исполняемый.
SSH-доступ к целевой системе (Target System)
QtCreator использует OpenSSH для копирования файлов с ПК разработчика в целевую систему. Итак, OpenSSH должен быть установлен как на вашем компьютере, так и на целевом компьютере. QtCreator не работает с Dropbear, облегченной альтернативой OpenSSH для встроенных систем.
Для входа в SSH QtCreator предлагает аутентификацию по паролю и аутентификацию с открытым ключом. Аутентификация по паролю требует, чтобы вы вводили пароль всякий раз, когда развертываете приложение в целевой системе. Это быстро становится утомительным. Итак, вы хотите использовать аутентификацию с открытым ключом.
Для этого вы создаете закрытые (private) и открытые (public) ключи на своем ПК с помощью ssh-keygen .
$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/burkhard/.ssh/id_rsa): /home/burkhard/.ssh/touch21-id_rsa Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/burkhard/.ssh/touch21-id_rsa. Your public key has been saved in /home/burkhard/.ssh/touch21-id_rsa.pub. ...
Вы оставляете парольную фразу пустой, нажимая Return и уведомляете агента SSH о новом ключе.
$ ssh-add ~/.ssh/touch21-id_rsa
Копируете открытый (public) ключ в целевую систему.
$ scp ~/.ssh/touch21-id_rsa.pub benutzer@192.168.1.82:/home/benutzer/.ssh
Заменяете benutzer и 192.168.1.82 с IP-адресом целевой системы своим именем пользователя в целевой системе.
Входите в целевую систему и добавляете открытый ключ в файл ~/.ssh/authorized_keys .
On host: $ ssh benutzer@192.168.1.82 => Enter your password On target: # cat ~/.ssh/touch21-id_rsa.pub > ~/.ssh/authorized_keys
При следующем входе в целевую систему вам больше не нужно будет вводить пароль. SSH проверяет, имеет ли пользователь, выполняющий вход, закрытый ключ одного из открытых ключей, хранящихся в ~/.ssh/authorized_keys . QtCreator будет использовать тот же механизм для развертывания файлов приложения.
Создание Docker Qt Kit
Вам нужно определить набор, который использует сценарий dr-cmake вместо cmake и знает, как войти в целевую систему с помощью SSH, развертывает файлы приложения и библиотеки Qt в целевой системе.
Настройка: CMake
Откройте диалоговое окно Tools > Options > Kits > CMake (Инструменты > Параметры > Комплекты > CMake) и нажмите кнопку Добавить. Заполните поля, как показано на скриншоте, и нажмите кнопку Apply (Применить) .
Настройка: Qt Version
Перейдите в одноуровневый диалог Tools > Options > Kits > Qt Versions (Инструменты > Параметры > Комплекты > Версии Qt) и нажмите кнопку Add (Добавить) . Перейдите к двоичному файлу QMake той версии Qt, которую вы установили в своем рабочем каталоге. Например, QMake разработчика находится по адресу /public/Work/qt-5.14.1/bin/qmake . Добавьте префикс Version name with Docker (имени версии в Docker ), чтобы эту версию Qt было легко распознать. Нажмите кнопку Apply (Применить) , чтобы сохранить конфигурацию.
Настройка: Device (устройства)
Перейдите в диалог Tools > Options > Devices (Инструменты > Параметры > Устройства) , чтобы добавить информацию для входа в SSH. На вкладке Devices нажмите кнопку Add (Добавить) , выберите Generic Linux Device в отдельном всплывающем диалоговом окне и нажмите кнопку Start Wizard . Для разработчика первая страница wizard выглядит так:
У вас будут разные значения для имени, IP-адреса и имени пользователя. Нажмите кнопку Next (Далее) , чтобы перейти ко второй странице wizard. Вы переходите к закрытому ключу SSH, который вы создали ранее.
Поскольку вы уже развернули открытый ключ, вы переходите на третью и последнюю страницу wizard, нажав кнопку Next (Далее) . Последняя страница выглядит следующим образом.
Нажмите кнопку Finish (Готово) . Диалог для успешного тестирования подключения выглядит следующим образом.
Полностью заполненная форма для нового устройства Touch21 выглядит примерно так.
Настройка: Kit (комплект)
Вы определили все части: CMake, Qt Version и Device для настройки Kit. Вернитесь в диалоговое окно Tools > Options > Kits > Kits (Инструменты > Параметры > Комплекты > Комплекты) и нажмите кнопку Add (Добавить) . Заполните форму, как показано на следующем скриншоте.
Нажмите кнопку Change (Изменить) для CMake Configuration внизу и замените содержимое диалога следующими тремя строками.
CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} CMAKE_PREFIX_PATH:STRING=/public/Work/qt-5.14.1
Не забудьте заменить рабочий каталог разработчика /public/Work вашим. Вот как должен выглядеть диалог прежде, чем нажать кнопку OK .
Конфигурирование проекта
Если вы открываете файл проекта /public/Work/qtcreator-with-docker/CMakeLists.txt в первый раз, QtCreator попросит вас настроить проект (см. Следующий снимок экрана). Выберите набор Docker Qt 5.14.1, который вы только что создали, и нажмите кнопку Configure Project (Настроить проект) .
Если вы открывали ранее проект с другой конфигурацией, то вы нажимаете на запись Docker Qt 5.14.1 в списке ниже Build & Run и на подпункт Build .
В обоих случаях вы увидите типичные сообщения CMake в панели вывода General Messages (Общие сообщения) при создании Makefiles (Make-файлов) в первый раз. Посмотрите на первую строку: QtCreator вызывает скрипт dr-cmake вместо cmake . Контейнер Docker блокирует соединение сокетов, которое пытается установить сервер CMake option -E. Это вызывает сообщения об ошибках QLocalSocket::connectToServer: Invalid name . Тем не менее, вызов CMake работает.
Running "/home/burkhard/bin/dr-cmake -E server --pipe=/tmp/cmake-.JRorEM/socket --experimental" in /tmp/QtCreator-jZQYdh/qtc-cmake-cbJJnSrf. QLocalSocket::connectToServer: Invalid name ... Starting to parse CMake project, using: "-DCMAKE_BUILD_TYPE:STRING=Debug", "-DCMAKE_CXX_COMPILER:STRING=/usr/bin/g++", "-DCMAKE_C_COMPILER:STRING=/usr/bin/gcc", "-DCMAKE_PREFIX_PATH:STRING=/public/Work/qt-5.14.1". The C compiler identification is GNU 7.4.0 The CXX compiler identification is GNU 7.4.0 ... Check for working CXX compiler: /usr/bin/g++ Check for working CXX compiler: /usr/bin/g++ -- works Detecting CXX compiler ABI info Detecting CXX compiler ABI info - done Detecting CXX compile features Detecting CXX compile features - done Configuring done Generating done CMake Project was parsed successfully.
Откройте настройки сборки Projects > Build & Run > Docker Qt 5.14.1 > Build и нажмите кнопку Add Build Step > Build . Проверьте установку (install) в поле Targets (Цели) и снимите все остальные цели. Следующий снимок экрана показывает окончательные настройки сборки. Обратите внимание, что dr-cmake используется на этапах сборки и очистки вместо cmake .
Переключитесь на настройки запуска Projects > Build & Run > Docker Qt 5.14.1 > Run . Удалите раздел Install (Установка) во temporary host directory (временную директорию хоста) , наведя курсор на кнопку Details (Подробности) и нажав на крестик слева от кнопки Details. Остальная же часть раздела развертывания в порядке.
Когда вы построите проект хотя бы один раз, вы увидите все Files to deploy (файлы для развертывания) в окне с тем же именем. Список файлов сообщает QtCreator, в какие удаленные каталоги он должен копировать локальные файлы при развертывании. Вот пример записи:
/public/Work/qt-5.14.1/lib/libQt5Multimedia.so.5.14.1 -> /home/benutzer/MyComp/qt/lib/
QtCreator читает отображение из локальных файлов в удаленные каталоги из файла QtCreatorDeployment.txt . Макросы add_deployment_file и add_deployment_directory заносят записи сопоставления в QtCreatorDeployment.txt .
Отображение содержит две записи для исполняемого файла приложения.
/public/Work/build-qtcreator-with-docker-Docker_Qt_5_14_1-Debug/final/bin/SimpleApp -> /home/benutzer/MyComp/bin /public/Work/build-qtcreator-with-docker-Docker_Qt_5_14_1-Debug/SimpleApp -> /home/benutzer/MyComp/.
Вторая запись происходит от вызова install(TARGETS). Исполняемый файл является результатом шага сборки CMake. Он содержит последовательность двоеточий вместо rpath. Он не будет работать в целевой системе, потому что не найдет библиотеки Qt. Шаг установки CMake заменяет последовательность двоеточий относительными rpaths. Результатом шага установки является исполняемый файл первой записи, который вытекает из вызова add_deployment_file. Исполняемый файл первой записи - это тот, который QtCreator будет запускать в целевой системе.
Если вы используете QtCreator 4.11.0 или новее и CMake 3.14 или новее, вам больше не понадобится обходной путь с файлом QtCreatorDeployment.txt . QtCreator и CMake работают вместе, чтобы создать отображение из команд установки. Тем не менее, Ubuntu 18.04 поставляется с CMake 3.10, поэтому вам все еще нужен обходной путь.
В разделе Run (Запуск) в Run configuration (конфигурации запуска) должно быть указано SimpleApp (on Touch21) . В поле под Run configuration введите следующие значения.
• В строке
Alternate executable on device (Альтернативный исполняемый файл на устройстве)
установите флажок
Use this command instead (Использовать эту команду)
и введите полный путь к исполняемому файлу на целевом устройстве (для разработчика:
/home/benutzer/MyComp/bin/SimpleApp)
.
• В строке
Command line arguments (Аргументы командной строки)
введите аргументы, необходимые для приложения (для разработчика:
-platform xcb -plugin evdevtouch)
.
В разделе Run Environment (запуск среды выполнения) вы добавляете переменную DISPLAY со значением: 0.
Запуск приложения в целевой системе
Теперь наступает волшебный момент. Вы нажимаете
Ctrl+R (Run)
в QtCreator. QtCreator создает приложение, развертывает приложение и библиотеки Qt на целевом устройстве, и запускает его на целевом устройстве. Все это за один шаг.
Вы видите вызовы QtCreator Docker-CMake и вызовы развертывания на
Compile Output pane (панель Компилировать вывод)
. Вот сокращенная версия (за исключением сообщений компилятора и прогресса).
11:19:37: Running steps for project SimpleApp... 11:19:37: Persisting CMake state... 11:19:37: Starting: "/home/burkhard/bin/dr-cmake" --build . --target all ... 11:19:39: The process "/home/burkhard/bin/dr-cmake" exited normally. 11:19:39: Starting: "/home/burkhard/bin/dr-cmake" --build . --target install ... 11:19:43: The process "/home/burkhard/bin/dr-cmake" exited normally. 11:19:43: Connecting to device "Touch21" (192.168.1.82). 11:19:44: The remote file system has 985 megabytes of free space, going ahead. 11:19:44: Deploy step finished. 11:19:44: Trying to kill "/home/benutzer/MyComp/bin/SimpleApp" on remote device... 11:19:45: Remote application killed. 11:19:45: Deploy step finished. 11:19:45: sending incremental file list 11:19:45: SimpleApp ... total size is 751,048 speedup is 1.00 11:22:24: Deploy step finished. 11:22:24: Elapsed time: 02:47.
Первое развертывание занимает пару минут (у разработчика заняло 2:47 минут), потому что QtCreator копирует части времени выполнения Qt с ПК разработчика в целевую систему. Пока Qt не меняется, вы можете пропустить развертывание Qt. Перейдите в настройки сборки
Projects > Build & Run > Docker Qt 5.14.1 > Build
, установите для переменной DEPLOY_QT значение OFF в разделе
CMake
и нажмите кнопку
Apply Configuration Changes
.
Теперь ваш рабочий процесс такой же, как если бы вы запускали приложение на своем ПК для разработки. Вы меняете свой код и создаете, развертываете и запускаете приложение, нажимая
Ctrl+R
в Qt Creator, а потом вы можете попробовать свои изменения в целевой системе. Вы немедленно получаете обратную связь о том, как ваши изменения ведут себя в целевой системе.