Сборка Docker из QtCreator

Docker, Qt, QtCreator, build, cmake

Content

На своем компьютере для разработок нажимаете 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, а потом вы можете попробовать свои изменения в целевой системе. Вы немедленно получаете обратную связь о том, как ваши изменения ведут себя в целевой системе.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate

Comments

Only authorized users can post comments.
Please, Log in or Sign up
How to become an author?

Contribute to the evolution of the EVILEG community.

Learn how to become a site author.

Learn it
Donate

Good day, Dear Users!!!

I am Evgenii Legotckoi, developer of EVILEG. And it is my hobby project, which helps to learn programming another programmers and developers

If the site helped you, and you want also support the development of the site, than you can donate by following ways

PayPalYandex.Money
Timeweb

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting Timeweb
June 5, 2020, 11:20 p.m.
Aleksej

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:60points,
  • Rating points-1
June 5, 2020, 11:15 p.m.
Aleksej

C++ - Test 001. The first program and data types

  • Result:53points,
  • Rating points-4
V
June 5, 2020, 4:47 p.m.
Vladzo

C++ - Test 005. Structures and Classes

  • Result:83points,
  • Rating points4
Last comments
June 5, 2020, 10:52 a.m.
progammist

Распознавание изображений на Python с помощью TensorFlow и Keras

Огромное спасибо за метериал, по-больше бы подобных статей (с подробным описанием работы и примерами применения) на тему современных технологий. Вопрос поразмышлять. На текущий момент реал…
June 5, 2020, 1:39 a.m.
Evgenij Legotskoj

Qt/C++ - Tutorial 091. How to write a custom delegate controlling the highlighting of a row in a table

По-моему, смысла в этом нет особого. Если делегат будет игнорировать настройки таблицы, то это приведёт ещё к большему непониманию, что вообще происходит, для программиста, который после вас буд…
June 5, 2020, 1:34 a.m.
IscanderChe

Qt/C++ - Tutorial 091. How to write a custom delegate controlling the highlighting of a row in a table

Сижу, размышляю: можно ли переписать делегата так, чтобы независимо от настроек строк выделялись строки?
June 5, 2020, 1:31 a.m.
Evgenij Legotskoj

Qt/C++ - Tutorial 091. How to write a custom delegate controlling the highlighting of a row in a table

Понятно. Я не обратил внимания на то, что там было в старом коде по настройкам строк :)
Now discuss on the forum
s
June 6, 2020, 1:54 a.m.
shuric

Qt/C++ Определение положения курсора над действие(кнопкой) в QToolBar

Доброго дня. Возник вопрос - как можно определить что курсор находится над определенным действием(кнопкой) в qtoolbar ? mainwindow.cpp MainWindow::MainWi…
s
June 6, 2020, 12:45 a.m.
shuric

Qt/C++ особенности QProxyStyle

Да, Вы правы. Код был скопирован с сайта (уже не помню с какого), но решил пойти по пути более легком. Пришлось переписать - кому интересно: использовал stackedWidget для пе…
June 5, 2020, 11:08 p.m.
Aleksej

Посоветуйте новичку (базы данных и Qt, что учить)

Блин, а я недавно купил Шлее Qt 5.10 :( С детства хотел стать программистом, баловался Паскалем, писал простенькие программки на Delphi, создавал движок на php, изучал C (забросил и перешел на п…
June 5, 2020, 1:09 p.m.
IscanderChe

QPlainTextEdit настройка цвета фона

Вечер добрый. Пытаюсь настроить цвет фона QPlainTextEdit следующим образом: CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent){ ... QPalette::ColorRole role = bac…
June 5, 2020, 6:13 a.m.
IscanderChe

Фильтр для QtableView sql

Добрый день. Для такой фильтрации необходимо использовать QSortFilterProxyModel. В оффдоках есть хороший пример.
About
Services
© EVILEG 2015-2020
Recommend hosting TIMEWEB