172 lines
12 KiB
Markdown
172 lines
12 KiB
Markdown
# Сборка, упаковка и релизы
|
||
|
||
## Что нужно
|
||
|
||
- CMake 3.20+, компилятор C++17 и C (C нужен для zlib на Linux).
|
||
- Qt 6.8 или новее (`qt_standard_project_setup(REQUIRES 6.8)`). CI собирает на Qt 6.11.1.
|
||
- Обязательные модули: `Quick`, `QuickControls2`, `Qml`, `Svg`, `Core`, `CorePrivate`, `Gui`,
|
||
`Network`.
|
||
- Необязательный: `WebEngineQuick`, для входа через Microsoft.
|
||
|
||
`CorePrivate` нужен ради `QZipReader` и `QZipWriter`: ими распаковываются нативные библиотеки
|
||
LWJGL, архивы Temurin и архивы сборок. Приватные модули Qt не гарантируют совместимость между
|
||
версиями, поэтому проект привязан к конкретной версии Qt. Предупреждение об этом отключено
|
||
(`QT_NO_PRIVATE_MODULE_WARNING`).
|
||
|
||
### Qt WebEngine
|
||
|
||
Модуль ставится в MaintenanceTool отдельной галочкой и тянет за собой Qt WebChannel и Qt
|
||
Positioning. Чтобы он работал, нужны все три.
|
||
|
||
Если сделать WebEngine обязательным, у любого, кто его не поставил, проект вообще не соберётся,
|
||
хотя офлайн-вход и Ely.by без него работают. Поэтому:
|
||
|
||
- модуль найден — определяется `LAUNCHER_HAS_WEBENGINE`, `MicrosoftLoginDialog.qml` попадает в
|
||
модуль, `backend.microsoftAvailable` равно `true`;
|
||
- не найден — CMake выдаёт предупреждение со списком компонентов, которые надо доставить, а
|
||
лаунчер собирается без входа через Microsoft.
|
||
|
||
Релизные сборки в CI всегда с WebEngine: скрипты подготовки раннеров проверяют, что он есть.
|
||
|
||
## Локальная сборка
|
||
|
||
```bash
|
||
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$HOME/Qt/6.11.1/macos
|
||
```
|
||
|
||
```bash
|
||
cmake --build build
|
||
```
|
||
|
||
Из Qt Creator проект открывается как обычный CMake-проект.
|
||
|
||
Версия приложения задаётся в одном месте, в `project(BiLauncher VERSION x.y.z)`. Оттуда она идёт в
|
||
`LAUNCHER_VERSION`, в ресурс версии `.exe`, в `Info.plist` и в имена файлов релиза.
|
||
|
||
## Что собирается
|
||
|
||
**`BiLauncher`** — исполняемый файл и QML-модуль с URI `BiLauncher`. В модуль входят все `.cpp`,
|
||
`.qml`, картинки из `images/`, `i18n/translations.json`, а также `CHANGELOG.md`, `LICENSE` и
|
||
`README.md`. Последние три сейчас никто из кода не читает, они просто лежат в ресурсах.
|
||
|
||
QML-модуль собирается в `<build>/qml/BiLauncher` (`OUTPUT_DIRECTORY`). Если оставить по
|
||
умолчанию, на Linux папка `BiLauncher` совпадёт по имени с исполняемым файлом (у него нет
|
||
расширения), и линковка упадёт с «Is a directory».
|
||
|
||
**`launcher_zlib_reference`** — только на Linux. Это обычный zlib 1.3.1 из каталога `zlib/`,
|
||
выходной файл `libz.so.1` в `<build>/zlib/`. С ним лаунчер не линкуется. Библиотека нужна только
|
||
установщикам Forge и NeoForge на системах с zlib-ng, см. [zlibreference.h](cpp/zlibreference.md).
|
||
Исходники zlib — чужой код из upstream, документацией он не покрыт.
|
||
|
||
## Иконки
|
||
|
||
Все размеры собираются из одного файла `icons/master/icon_master.png` (1024×1024, рисунок до краёв
|
||
холста) скриптом `icons/generate_icons.sh`. Для него нужны ImageMagick и `iconutil`, то есть
|
||
запускается он на macOS. Правки вносятся в мастер, после чего скрипт перезапускается. Отдельные
|
||
размеры руками не правятся.
|
||
|
||
Системы по-разному добавляют поля вокруг иконки, поэтому один и тот же рисунок кладётся
|
||
по-разному:
|
||
|
||
- **macOS** сама поля не добавляет. По сетке Apple рисунок занимает 824 из 1024 точек, углы
|
||
скруглены радиусом 185.4. Результат — `icon.icns`, кладётся в `Contents/Resources` бандла.
|
||
- **Windows** ждёт картинку на весь холст. `icon.ico` содержит кадры 16–256, включая 20, 40 и 96
|
||
для масштабов 125/150/200%. Без явного списка ImageMagick положил бы в `.ico` только 1024×1024,
|
||
и система размывала бы иконку при уменьшении. Вкомпилирована через `icon.rc.in`, где заодно
|
||
ресурс версии.
|
||
- **Linux**: PNG 16–512 ставятся в тему `hicolor` под именем `bilauncher.png`, плюс
|
||
`bilauncher.desktop`. Окружения рабочего стола ищут иконку по имени из `Icon=`, а не по имени
|
||
файла.
|
||
|
||
Иконка окна задаётся в `main.cpp` из ресурса `:/icons/` (на всех системах, кроме macOS).
|
||
|
||
## Установка (`cmake --install`)
|
||
|
||
- исполняемый файл в `bin/` (на macOS — `BiLauncher.app`);
|
||
- `qt_generate_deploy_qml_app_script` раскладывает рядом Qt, плагины и QML-модули
|
||
(windeployqt/macdeployqt под капотом; на macOS с `-hardened-runtime`);
|
||
- `LICENSE`, `CHANGELOG.md`, `packaging/THIRD_PARTY_LICENSES.txt` в `share/doc/BiLauncher/` (кроме
|
||
macOS);
|
||
- на Linux ещё `libz.so.1` в `lib/BiLauncher/`, иконки и `.desktop`.
|
||
|
||
На Linux ставьте с `-DCMAKE_INSTALL_LIBDIR=lib`. Лаунчер ищет эталонный zlib в
|
||
`<bin>/../lib/BiLauncher`, а на Ubuntu по умолчанию `LIBDIR` был бы `lib/x86_64-linux-gnu`.
|
||
|
||
## Релизы
|
||
|
||
Релизы собирает Gitea Actions, `.gitea/workflows/release.yml`.
|
||
|
||
### Как выпустить версию
|
||
|
||
1. Поднять версию в `project(BiLauncher VERSION ...)` в `CMakeLists.txt`.
|
||
2. Добавить в `CHANGELOG.md` раздел `## [x.y.z] — дата`. Его текст станет описанием релиза.
|
||
3. Закоммитить и запушить тег `vx.y.z`. Для предрелиза — `vx.y.z-rc1` (всё после дефиса делает
|
||
релиз pre-release).
|
||
|
||
Если тег не совпадает с версией в `CMakeLists.txt` (без учёта суффикса), прогон сразу падает.
|
||
|
||
### Что происходит
|
||
|
||
1. **create-release** (Linux) — сверяет тег с версией, вырезает раздел из `CHANGELOG.md` и
|
||
создаёт **черновик** релиза.
|
||
2. Параллельно три сборки, каждая прикладывает свои файлы к черновику:
|
||
- **Linux**: `BiLauncher-<v>-x86_64.AppImage` и `BiLauncher-<v>-linux-x86_64.tar.gz`. Сборка
|
||
идёт с `-j 8`: на ВМ 6 ГБ памяти, и без ограничения компиляторы съедают её всю.
|
||
- **Windows**: `BiLauncher-<v>-win64-setup.exe` (Inno Setup) и
|
||
`BiLauncher-<v>-win64-portable.zip`. В portable нет `vc_redist`, среда выполнения MSVC должна
|
||
уже стоять в системе. Сборка идёт в `C:\r\...`, потому что дерево WebEngine легко выходит за
|
||
`MAX_PATH`. Zip делается системным `tar.exe` по полному пути: GNU tar из Git, который стоит в
|
||
`PATH` раньше, zip не умеет и принимает `C:` за имя удалённого хоста.
|
||
- **macOS**: `BiLauncher-<v>-macOS-universal.dmg` (arm64 + x86_64). Подпись ad-hoc: без неё
|
||
приложение вообще не запустится на Apple Silicon. Developer ID нет, поэтому Gatekeeper при
|
||
первом запуске всё равно спросит подтверждение.
|
||
3. **publish** собирает `SHA256SUMS.txt` из хешей всех трёх сборок, прикладывает его и снимает с
|
||
релиза флаг черновика.
|
||
|
||
Если хоть одна сборка упала, релиз остаётся черновиком и пользователи его не видят.
|
||
|
||
Ручной запуск (`workflow_dispatch`) делает те же сборки, но релиз не создаёт: файлы остаются
|
||
артефактами прогона.
|
||
|
||
Секрет `RELEASE_TOKEN` — персональный токен Gitea с правом `repository: write`.
|
||
|
||
### Установщик Windows
|
||
|
||
`packaging/windows/BiLauncher.iss` (Inno Setup 6). Ставит в `Program Files\BiLauncher`, разрешает
|
||
выбрать установку только для текущего пользователя, создаёт ярлык в меню «Пуск» и, по желанию, на
|
||
рабочем столе, тихо ставит `vc_redist`, если он есть в дереве. Языки установщика — русский и
|
||
английский.
|
||
|
||
`AppId` менять нельзя: по нему новая версия находит и обновляет старую установку.
|
||
|
||
## Раннеры
|
||
|
||
Раннеры работают в режиме host, то есть прямо на машине, без Docker. Метки: `linux`, `windows`,
|
||
`macos`.
|
||
|
||
Пути к Qt раннер передаёт сборке через переменные окружения в своём `config.yaml`:
|
||
|
||
- `QT_ROOT` — kit Qt (например, `~/Qt/6.11.1/gcc_64`);
|
||
- `QT_TOOLS` — папка `Tools` из Qt Online Installer, оттуда CMake и Ninja;
|
||
- `ISCC_DIR` — только Windows, папка Inno Setup.
|
||
|
||
Qt с WebEngine, CMake и Ninja ставятся заранее через Qt Online Installer. Скрипты подготовки
|
||
докачивают остальное и регистрируют раннер. Повторный запуск безопасен.
|
||
|
||
**Linux** (Ubuntu 22.04), `ci/setup-runner-linux.sh [токен]`. Запускать от пользователя, которому
|
||
принадлежит Qt, нужен sudo без пароля. Ставит компилятор, библиотеки для сборки и деплоя (xcb,
|
||
OpenGL, NSS и т. д.), `libfuse2` для appimagetool, Node.js (нужен `actions/checkout`), appimagetool,
|
||
gitea-runner и systemd-сервис `gitea-runner`.
|
||
|
||
**Windows**, `ci/setup-runner-windows.ps1 [-Token ...]` из PowerShell от администратора. Ставит
|
||
VS 2022 Build Tools (это 20–40 минут), Git, Node.js, Inno Setup, включает длинные пути в системе и
|
||
в git, регистрирует gitea-runner. Раннер запускается задачей планировщика при входе пользователя,
|
||
поэтому пароль учётной записи не нужен, но без входа в систему раннер не поднимется. Чтобы он
|
||
стартовал при загрузке машины, задачу нужно пересоздать с `/sc onstart /rp *`.
|
||
|
||
**macOS** — скрипта подготовки нет, раннер настроен вручную.
|
||
|
||
---
|
||
|
||
При создании этого документа использовался ИИ.
|