Думать о проекте без CI/CD невообразимо, тем более для кросс-платформенного приложения, где нам приходится переключаться между несколькими платформами.
CI/CD
Непрерывная интеграция (CI) и непрерывная поставка (CD) предлагают несколько преимуществ:
- Небольшие изменения кода.
- Более быстрая скорость выпуска.
- Повышение удовлетворенности пользователей.
- Более простое обслуживание.
Для проектов на основе Qt, которые по своей структуре являются кроссплатформенными, конвейер CI/CD будет иметь несколько дополнительных преимуществ:
- Не нужно крутить несколько машин под каждую ОС.
- Надежные и воспроизводимые сборки для всех целевых ОС.
- Более простая и быстрая интеграция изменений.
Далее мы увидим, как настроить базовый компакт-диск GitHub Actions для получения двоичных файлов нашего программного обеспечения для Windows, Linux и MacOS. Во второй части мы увидим, как создать онлайн- и автономный установщик Windows с помощью QtInstallerFrameWork.
Инструменты
Для создания нашего пайплайна мы будем использовать несколько инструментов, основной из которых — GitHub Actions framework, Aqtinstall — установщик командной строки для Qt и qmake для компиляции программы Qt.
Окна
Сначала мы создаем папку«.github/workflows» внутри репозитория git нашего проекта. Затем создайте действие с именем «windows.yml».
name: Build Windows
on:
push:
branches: [master]
Photo by Vidar Nordli-Mathisen on Unsplash
jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: ilammy/msvc-dev-cmd@v1
- uses: actions/setup-python@v2
with:
python-version: '3.8'
- name: install qt6
run: |
pip install aqtinstall
python3 -m aqt install-qt -m qtwebengine qtwebchannel qtpositioning -O ${{ github.workspace }}/Qt/ windows desktop 6.2.0 win64_msvc2019_64
echo "${{ github.workspace }}/Qt/6.2.0/msvc2019_64/bin/" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: build
shell: cmd
run: |
cd src/
qmake6 Program.pro -spec win32-msvc
nmake release
nmake clean
cd release
windeployqt Program.exe --release --compiler-runtime
copy ..\assets\icon.ico .
copy C:\Windows\System32\concrt140.dll .
copy C:\Windows\System32\vccorlib140.dll
.
copy C:\Windows\System32\msvcp140.dll .
copy C:\Windows\System32\vcruntime140.dll .
7z a C:\Program.zip *
- name: Windows artefact
uses: actions/upload-artifact@v1
with:
name: WindowsBuild
path: C:\Program.zip
Во-первых, мы назовем Действия (Сборка Windows) и выберем, когда они будут запускаться, в данном случае при каждой фиксации в ветке master.
Затем мы создаем задание и выбираем средство запуска GitHub, в нашем случае — последнюю доступную версию Windows.
actions/checkout@v2 будет клонировать репозиторий, а ilammy/msvc-dev-cmd@v1настроит среду, в которой мы сможем использовать nmake . Наконец, actions/setup-python@v2 настроит среду Python.
Мы используем aqtinstall для установки Qt на машину. В этом примере мы устанавливаем несколько модулей (qtwebengine, qtwebchannel, qtpositioning) вместе с версией Qt 6.2.0 для 64-разрядной версии MSVC 2019. Наконец, мы устанавливаем путь к установке Qt, используя переменную $env:GITHUB_PATH.
Как обычно, мы собираем программу, используя qmake и nmake.
На этом этапе мы создали один двоичный файл. Чтобы развернуть приложение, нам нужно скопировать соответствующие библиотеки, необходимые для выполнения. Мы используем имя инструмента Qt windeployqt. Имейте в виду, что этот инструмент не будет копировать внешние (не Qt) библиотеки, этот шаг необходимо выполнить вручную. Кроме того, мы вручную копируем несколько dll, которые необходимо распространить для обеспечения автономного выполнения (см. раздел https://doc.qt.io/qt-5/windows-deployment.html Создание пакета приложения).
Наконец, мы используем actions/upload-artifact@v1, чтобы загрузить результирующую папку в качестве артефакта Action, который мы сможем загрузить.
MacOS
macos.yml:
name: Build MacOs on: push: branches: [master] jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: '3.8' - name: install qt6 run: | pip install aqtinstall python3 -m aqt install-qt -m qtwebengine qtwebchannel qtpositioning -O ${{ github.workspace }}/Qt/ mac desktop 6.2.0 echo ${{ github.workspace }}/Qt/6.2.0/macos/bin/ >> $GITHUB_PATH - name: build run: | qmake6 src/Program.pro make make clean cd build/ macdeployqt Program.app -always-overwrite wget https://raw.githubusercontent.com/arl/macdeployqtfix/master/macdeployqtfix.py python2.7 macdeployqtfix.py Program.app/Contents/MacOS/Program ../../Qt/6.2.0/ hdiutil create -volname Program -srcfolder Program.app -ov -format UDZO Program.dmg - name: Mac artefact uses: actions/upload-artifact@v1 with: name: MacOsBuild path: ./build/Program.dmg
Процедура для MacOs аналогична. В конце компиляции мы используем macdeployqt, чтобы скопировать нужные библиотеки в бандл и задать правильные rpaths. Для внешних зависимостей возможно, что macdeployqt не завершает работу, чтобы исправить это, мы используем macdeployqtfix. Наконец,мы упаковываем приложение как файл dmg.
линукс
Существует несколько способов выпуска пакетов для Linux, в этом примере мы используем формат AppImage, который будет совместим со всеми дистрибутивами Linux.
linux.yml:
name: Build AppImage on: push: branches: [master] jobs: job_1: runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: '3.8' - name: install qt6 run: | pip install aqtinstall python3 -m aqt install-qt -m qtwebengine qtwebchannel qtpositioning -O ${{ github.workspace }}/Qt/ linux desktop 6.2.0 echo ${{ github.workspace }}/Qt/6.2.0/gcc_64/bin/ >> $GITHUB_PATH - name: build run: | qmake6 src/Program.pro make make clean - name: appimage run: | cd build wget -O deploy.AppImage https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage chmod +x deploy.AppImage export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${{ github.workspace }}/Qt/6.2.0/gcc_64/lib/ ./deploy.AppImage Program -appimage -no-translations -bundle-non-qt-libs mv Program*.AppImage Program-x86_64.AppImage - name: Linux artefact uses: actions/upload-artifact@v1 with: name: LinuxBuild path: ./build/Program-x86_64.AppImage
Что касается другого, процедура такая же. Мы используем linuxdeployqt для создания файла AppImage в конце перед загрузкой файла в качестве артефакта действия.
Вывод
Настройка CI/CD, которая будет собирать программу Qt в Linux, Windows и MacOs, не очень сложна и приведет к значительной экономии времени. В следующей части серии Qt мы увидим, как создавать исполняемые файлы (автономные и онлайновые) для Windows с помощью Qt Installer Framework и GitHub Actions.