# Сборка, упаковка и релизы ## Что нужно - 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-модуль собирается в `/qml/BiLauncher` (`OUTPUT_DIRECTORY`). Если оставить по умолчанию, на Linux папка `BiLauncher` совпадёт по имени с исполняемым файлом (у него нет расширения), и линковка упадёт с «Is a directory». **`launcher_zlib_reference`** — только на Linux. Это обычный zlib 1.3.1 из каталога `zlib/`, выходной файл `libz.so.1` в `/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 в `/../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--x86_64.AppImage` и `BiLauncher--linux-x86_64.tar.gz`. Сборка идёт с `-j 8`: на ВМ 6 ГБ памяти, и без ограничения компиляторы съедают её всю. - **Windows**: `BiLauncher--win64-setup.exe` (Inno Setup) и `BiLauncher--win64-portable.zip`. В portable нет `vc_redist`, среда выполнения MSVC должна уже стоять в системе. Сборка идёт в `C:\r\...`, потому что дерево WebEngine легко выходит за `MAX_PATH`. Zip делается системным `tar.exe` по полному пути: GNU tar из Git, который стоит в `PATH` раньше, zip не умеет и принимает `C:` за имя удалённого хоста. - **macOS**: `BiLauncher--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** — скрипта подготовки нет, раннер настроен вручную. --- При создании этого документа использовался ИИ.