🔧 Кросс-сборка CLI и GUI-приложения на Rust — проблемы и решения
DotPlus — это Rust-приложение с графическим и консольным интерфейсом. Изначально оно разрабатывалось под Windows, но в планах была сборка под Linux и Docker.
Решение: добавить полноценные Linux-сборки с поддержкой GUI и CLI и обеспечить стабильную доставку под несколько архитектур.
❗ Почему не просто cargo build?
Если хочется стабильную сборку не только под x86_64, но и под ARM (Raspberry Pi, серверы), одной команды cargo build недостаточно. Возникают проблемы:
-
Нужны кросс-компиляторы (
gcc-aarch64-linux-gnuи др.) -
Требуется ручная настройка sysroot, musl, glibc
-
При использовании GUI (через
eframeиegui) иногда всплывают платформозависимые проблемы с OpenGL, зависимостями илиrfd(файловые диалоги)
🛠 Решение: cross-rs
Чтобы не городить окружения вручную и не писать десятки --target-флагов с настройкой toolchain, я решил использовать cross — это официальный инструмент от сообщества Rust, который:
-
Использует Docker-образы с преднастроенным окружением для каждой архитектуры
-
Упрощает кросс-компиляцию одной командой:
cross build --release --target aarch64-unknown-linux-gnu
-
Работает из коробки как с CLI, так и с GUI (если система сборки внутри контейнера поддерживает нужные dev-пакеты)
⚙️ Конфигурация: cross.toml
Вот пример моего cross.toml, где перечислены поддерживаемые архитектуры:
[target.aarch64-unknown-linux-gnu] image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:edge" [target.armv7-unknown-linux-gnueabihf] image = "ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:edge" [target.x86_64-unknown-linux-gnu] image = "ghcr.io/cross-rs/x86_64-unknown-linux-gnu:edge"
Образы edge — это свежие контейнеры с последними версиями компилятора и зависимостей. Именно они обеспечивают корректную сборку egui, eframe и rfd в Linux-окружении.
🧱 GUI + CLI: архитектура фич
[features] default = ["gui"] gui = ["eframe", "egui", "rfd", "egui_extras"] notifications = ["notify-rust"]
Благодаря этому:
-
Сборка CLI-версии возможна без GUI (
--no-default-features) -
На Linux можно собирать оба варианта одновременно, включая полноценное GTK/Wayland GUI через
eframe
Такой подход оказался крайне удобным: в одном проекте можно выпускать и headless-бинарник, и полноценное графическое приложение.
🪓 От чего пришлось отказаться
Несмотря на успех с cross, не обошлось без потерь:
-
musl-сборки (статически линкуемые) были отброшены —
eframeиrfdплохо работают в таком окружении -
Windows ARM MIPS и прочие экзотические платформы — слишком нестабильны и слабо поддерживаются в
cross -
Слишком «чистая» сборка без Docker — пришлось отказаться от идеи собирать без контейнеров, так как зависимостей GUI слишком много, и они не всегда есть на GitHub Actions runner’ах
✅ Что в итоге получилось
В результате, с помощью cross теперь собираются полноценные GUI+CLI бинарники под Linux для трёх платформ:
|
Архитектура |
Поддержка |
Назначение |
|
|
✅ GUI/CLI |
Десктопы и серверы |
|
|
✅ GUI/CLI |
ARM64 серверы, RPi 4 и новее |
|
|
✅ GUI/CLI |
RPi 3 и другие ARMv7 SBC |
✅ Итог: благодаря cross
DotPlus теперь полноценно работает на Linux с графическим интерфейсом и CLI. Одинаковый UX, стабильные сборки, возможность использовать на Raspberry Pi и сервере — всё это стало реальностью.
🚀 CI/CD: автоматизация сборки, кросс-компиляции и релизов
После успешной настройки cross для локальной кросс-компиляции стало ясно: ручной процесс не масштабируется. Хотелось воспроизводимой, полностью автоматизированной системы, которая при любом обновлении могла бы:
-
Собрать DotPlus под несколько архитектур
-
Подготовить установочные пакеты
.debи.rpm -
Собрать и опубликовать Docker-образ
-
Сформировать релиз и прикрепить артефакты
Так родился CI/CD-процесс на базе GitHub Actions, который покрывает весь цикл сборки и доставки.
📂 Общая структура
CI/CD реализован в одном workflow-файле 📄 build-multiarch.yml:
name: Build dotplus (.deb/.rpm) for all architectures on: push: branches: [linux] tags: ["v*"] workflow_dispatch: jobs: build: runs-on: ubuntu-latest env: CROSS_SKIP_VERSION_CHECK: "1" steps: - name: 🧾 Checkout uses: actions/checkout@v4 - name: ⚡️ Cache Cargo uses: actions/cache@v4 with: path: | ~/.cargo/bin ~/.cargo/registry ~/.cargo/git key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo- - name: 🧬 Enable QEMU for multi-arch RPM uses: docker/setup-qemu-action@v3 with: platforms: all - name: 🦀 Install Rust uses: actions-rs/toolchain@v1 with: toolchain: stable override: true components: rustfmt - name: 🎯 Add targets run: | rustup target add \ x86_64-unknown-linux-gnu \ aarch64-unknown-linux-gnu \ armv7-unknown-linux-gnueabihf - name: 🐳 Install Docker & Cross run: | sudo apt update sudo apt install -y docker.io containerd if ! command -v cross &>/dev/null; then cargo install cross else echo "✅ cross уже установлен, пропускаем" fi - name: 📦 Install deb/rpm tools run: | sudo apt install -y \ dpkg-dev debhelper rpm rpm2cpio fakeroot \ qemu-user-static binfmt-support \ gcc-multilib libc6-dev-i386 pkg-config \ libssl-dev libstdc++-12-dev - name: 🔧 Make script executable run: chmod +x tools/generate.sh - name: 🛠 Run build script run: ./tools/generate.sh - name: ☁️ Upload artifacts uses: actions/upload-artifact@v4 with: name: dotplus-packages path: | build/**/dotplus_*.deb build/**/RPMS/**/*.rpm docker: runs-on: ubuntu-latest needs: build steps: - name: 🧾 Checkout uses: actions/checkout@v4 - name: 🦀 Install Rust + cross run: | rustup update rustup target add x86_64-unknown-linux-musl cargo install cross - name: 🛠 Build static binary (musl, CLI-only) run: cross build --release --target x86_64-unknown-linux-musl --no-default-features - name: 🧰 Prepare Docker context run: | if [[ -f target/x86_64-unknown-linux-musl/release/dotplus ]]; then cp target/x86_64-unknown-linux-musl/release/dotplus docker/dotplus else echo "❌ Static binary not found" exit 1 fi - name: 🐳 Build Docker image run: docker build -t dotplus-cli -f docker/Dockerfile.cli ./docker - name: ☁️ Save Docker image as archive run: docker save dotplus-cli | gzip > dotplus-cli.tar.gz - name: ☁️ Upload Docker image artifact uses: actions/upload-artifact@v4 with: name: dotplus-cli-docker path: dotplus-cli.tar.gz
📄 build-multiarch.yml запускается при пуше в ветки release-linux или release-docker и выполняет сборку, упаковку, публикацию и деплой.
⚙️ Этапы пайплайна
Дата: 01.07.2025
Файл Workflow: build-multiarch.yml
Триггер: Push в ветку linux
📦 Этап 1: build (⏱ ~16 минут)
|
Шаг |
Описание |
|
⚙️ |
Инициализация задания |
|
📥 |
Клонирование репозитория |
|
⚡ |
Кэширование зависимостей |
|
🧩 |
Эмуляция архитектур |
|
🦀 |
Установка Rust |
|
🎯 |
Добавление целевых архитектур |
|
🐳 |
Установка Docker и |
|
🧰 |
Установка сборочных инструментов |
|
🔧 |
Подготовка сборочного скрипта |
|
▶️ |
Сборка |
|
⬆️ |
Загрузка артефактов |
|
♻️ Post-steps |
Очистка: откат QEMU, кэша и |
.deb, .rpm🐳 Этап 2: docker (⏱ ~4 минуты)
|
Шаг |
Описание |
|
⚙️ |
Инициализация задания |
|
📥 |
Клонирование репозитория |
|
🦀 |
Установка Rust + кросс-компиляция |
|
🛠 |
Сборка статичного бинарника (musl, CLI-only) |
|
🧳 |
Подготовка контекста для Docker |
|
🔨 |
Сборка образа |
|
💾 |
Сохранение Docker-образа в архив |
|
⬆️ |
Загрузка архива как артефакт |
|
♻️ Post-steps |
Очистка: откат |
🔄 Кросс-сборка бинарников
Кросс-компиляция происходит с использованием cross, который изолирует сборку в готовых Docker-образах:
- name: Build for aarch64 run: cross build --release --target aarch64-unknown-linux-gnu - name: Build for armv7 run: cross build --release --target armv7-unknown-linux-gnueabihf - name: Build for x86_64 run: cross build --release --target x86_64-unknown-linux-gnu
Это гарантирует одинаковые бинарники независимо от среды, включая GUI-часть на Linux.
📦 Пакетирование: .deb и .rpm из CI
-
dotplus_1.0.0_amd64.deb -
dotplus_1.0.0_arm64.deb -
dotplus_1.0.0_armhf.deb -
dotplus-1.0.0-1.x86_64.rpm
Установка на стороне пользователя:
sudo dpkg -i dotplus_1.0.0_amd64.deb # или sudo rpm -i dotplus-1.0.0-1.x86_64.rpm
🔧 Как это устроено?
Проект включает шаблоны:
templates/control.in — шаблон для .deb
Package: dotplus Version: {{VERSION}} Section: utils Priority: optional Architecture: {{ARCH}} Maintainer: Danil Nigmatullin <danil.communication@gmail.com> Depends: {{DEPENDS}} Description: QR and barcode generator with logo and CSV support (Rust CLI/GUI) DotPlus is a Rust-based GUI and command-line tool for generating QR codes and barcodes. It supports logo embedding, CSV import, and auto-update functionality. Suitable for both terminal workflows and desktop users.
templates/spec.in — шаблон для .rpm
Name: dotplus Version: {{VERSION}} Release: 1%{?dist} Summary: QR and barcode generator with logo and CSV support (Rust CLI/GUI) License: Freeware (Proprietary) URL: https://github.com/nigdanil/dotplus Source0: dotplus BuildArch: {{ARCH}} Requires: {{REQUIRES}} %description DotPlus is a Rust-based GUI and CLI tool for QR/barcode generation with logo and CSV support. %prep # No preparation steps needed %install [ -f %{SOURCE0} ] || { echo "Missing binary dotplus in SOURCES"; exit 1; } [ -f %{_sourcedir}/arialmt.ttf ] || { echo "Missing font file arialmt.ttf"; exit 1; } mkdir -p %{buildroot}/usr/bin mkdir -p %{buildroot}/usr/share/dotplus/fonts install -m 0755 %{SOURCE0} %{buildroot}/usr/bin/dotplus install -m 0644 %{_sourcedir}/arialmt.ttf %{buildroot}/usr/share/dotplus/fonts/arialmt.ttf %files /usr/bin/dotplus /usr/share/dotplus/fonts/arialmt.ttf %changelog * Mon Jun 30 2025 Danil Nigmatullin <danil.communication@gmail.com> - {{VERSION}}-1 - Initial RPM build
А также вспомогательный скрипт 📄 tools/generate.sh:
# tools/generate.sh #!/usr/bin/env bash set -e VERSION="1.0.0" echo "🚀 Starting multi-arch build: version $VERSION" START=$(date +%s) ARCHS=( "amd64" # x86_64-unknown-linux-gnu "arm64" # aarch64-unknown-linux-gnu "armhf" # armv7-unknown-linux-gnueabihf ) TARGETS=( "x86_64-unknown-linux-gnu" "aarch64-unknown-linux-gnu" "armv7-unknown-linux-gnueabihf" ) DEB_ARCHS=( "amd64" "arm64" "armhf" ) RPM_ARCHS=( "x86_64" "aarch64" "armv7hl" ) ROOT_DIR="$(git rev-parse --show-toplevel)" TEMPLATE_DIR="$ROOT_DIR/templates" mkdir -p build FAILED=() for i in "${!ARCHS[@]}"; do ARCH="${ARCHS[$i]}" TARGET="${TARGETS[$i]}" DEB_ARCH="${DEB_ARCHS[$i]}" RPM_ARCH="${RPM_ARCHS[$i]}" echo "🔧 Building for $ARCH ($TARGET)..." CROSS_SKIP_VERSION_CHECK=1 cross build \ --release \ --target "$TARGET" \ --manifest-path Cargo.toml \ --verbose || { echo "⚠️ Build failed for $TARGET"; FAILED+=("$ARCH"); continue; } BIN="target/$TARGET/release/dotplus" ls -lh "target/$TARGET/release" if [[ ! -f "$BIN" ]]; then echo "❌ Build failed for $TARGET" FAILED+=("$ARCH") continue fi BUILD_DIR="build/$ARCH" DEB_DIR="$BUILD_DIR/deb" RPM_DIR="$BUILD_DIR/rpm" mkdir -p "$DEB_DIR/DEBIAN" mkdir -p "$DEB_DIR/usr/bin" mkdir -p "$RPM_DIR/SOURCES" cp "$BIN" "$DEB_DIR/usr/bin/dotplus" cp "$BIN" "$RPM_DIR/SOURCES/dotplus" cp src/tools/font/arialmt.ttf "$RPM_DIR/SOURCES/arialmt.ttf" # Копируем ресурсные файлы (шрифты) mkdir -p "$DEB_DIR/usr/share/dotplus/fonts" cp src/tools/font/arialmt.ttf "$DEB_DIR/usr/share/dotplus/fonts/" # === .deb === sed \ -e "s/{{VERSION}}/$VERSION/" \ -e "s/{{ARCH}}/$DEB_ARCH/" \ -e "s/{{DEPENDS}}/libc6 (>= 2.29)/" \ "$TEMPLATE_DIR/control.in" > "$DEB_DIR/DEBIAN/control" dpkg-deb --build "$DEB_DIR" "$BUILD_DIR/dotplus_${VERSION}_${DEB_ARCH}.deb" # === .rpm === SPEC_OUT="$RPM_DIR/dotplus.spec" sed \ -e "s/{{VERSION}}/$VERSION/" \ -e "s/{{ARCH}}/$RPM_ARCH/" \ -e "s/{{REQUIRES}}/glibc >= 2.29/" \ "$TEMPLATE_DIR/spec.in" > "$SPEC_OUT" RPM_BUILDROOT="$RPM_DIR/BUILDROOT/dotplus-${VERSION}-1.${RPM_ARCH}" mkdir -p "$RPM_BUILDROOT/usr/bin" cp "$BIN" "$RPM_BUILDROOT/usr/bin/dotplus" chmod +x "$RPM_BUILDROOT/usr/bin/dotplus" # Копируем ресурсные файлы (шрифты) FONT_SOURCE="src/tools/font/arialmt.ttf" FONT_DEST="$RPM_DIR/BUILDROOT/dotplus-${VERSION}-1.${RPM_ARCH}/usr/share/dotplus/fonts" mkdir -p "$FONT_DEST" if [[ -f "$FONT_SOURCE" ]]; then cp "$FONT_SOURCE" "$FONT_DEST" echo "✅ Шрифт скопирован: $FONT_SOURCE → $FONT_DEST" else echo "⚠️ WARNING: $FONT_SOURCE не найден — удаляем строку из .spec" sed -i '/\/usr\/share\/dotplus\/fonts\/arialmt.ttf/d' "$SPEC_OUT" fi if [[ "$ARCH" == "amd64" ]]; then echo "📦 Building RPM for $ARCH..." rpmbuild \ --define "_topdir $ROOT_DIR/$RPM_DIR" \ --define "_sourcedir $ROOT_DIR/$RPM_DIR/SOURCES" \ --define "_builddir $ROOT_DIR/$RPM_DIR/BUILD" \ --define "_specdir $ROOT_DIR/$RPM_DIR" \ --define "_rpmdir $ROOT_DIR/$RPM_DIR/RPMS" \ --define "_buildrootdir $ROOT_DIR/$RPM_DIR/BUILDROOT" \ --target "$RPM_ARCH-redhat-linux" \ -bb "$SPEC_OUT" || { echo "❌ RPM build failed for $TARGET" FAILED+=("$ARCH") continue } RPM_OUTPUT=$(find "$RPM_DIR/RPMS" -name "*.rpm") if [[ -n "$RPM_OUTPUT" ]]; then echo "✅ RPM built for $ARCH: $RPM_OUTPUT" else echo "❌ RPM not found for $ARCH" FAILED+=("$ARCH") fi else echo "⚠️ Skipping RPM build for $ARCH" fi echo "✅ RPM build completed for $ARCH" echo "📁 RPM output dir listing:" ls -lR "$RPM_DIR" echo "📦 Checking built RPMs:" find "$RPM_DIR/RPMS" -type f 2>/dev/null || true done END=$(date +%s) DURATION=$((END - START)) if [[ ${#FAILED[@]} -gt 0 ]]; then echo "❌ Failed builds: ${FAILED[*]}" else echo "✅ All target builds succeeded" fi echo "🎉 Build finished in $DURATION seconds." # 🧪 Покажем, какие пакеты были созданы echo "📦 Built package files:" find build -type f \( -name "*.deb" -o -name "*.rpm" \) # Подсчёт количества .deb и .rpm PACKAGE_COUNT=$(find build -type f \( -name "*.deb" -o -name "*.rpm" \) | wc -l | tr -d '[:space:]') echo "🧪 DEBUG: Found packages:" FOUND_PACKAGES=$(find build -type f \( -name "*.deb" -o -name "*.rpm" \)) echo "$FOUND_PACKAGES" # Если ни одного пакета не создано — ошибка if [[ "$PACKAGE_COUNT" -lt 1 ]]; then echo "❌ No packages were created (check target paths or build errors)" echo "💡 Hint: verify that .deb and .rpm were written to expected build/**/ paths" exit 1 fi echo "✅ Total packages created: $PACKAGE_COUNT"
Он принимает бинарник и архитектуру, генерирует .deb/.rpm с помощью dpkg-deb и rpmbuild, и сохраняет итоговые пакеты для релиза.
🐳 Docker-сборка
После сборки бинарников запускается Docker-сборка CLI-варианта DotPlus:
- name: Build Docker image run: | docker build -f docker/Dockerfile.cli -t ghcr.io/nigdanil/dotplus:latest . docker push ghcr.io/nigdanil/dotplus:latest
Простой Dockerfile.cli использует минимальную базу и добавляет только бинарник:
FROM debian:bookworm-slim COPY dotplus /usr/local/bin/dotplus ENTRYPOINT ["dotplus"]
Публикация артефактов
Все собранные файлы (бинарники, .deb, .rpm) автоматически прикрепляются к GitHub Release. Это упрощает дистрибуцию: пользователи могут выбрать нужную архитектуру и просто скачать готовый пакет.
🧩 Что пришлось учесть
-
❌
muslиarm64-darwinне поддерживаются — нет стабильных образов или зависимости несовместимы -
⚠️
crossне кеширует образы между пушами, поэтому Docker нужен как для сборки, так и для доставки
📌 Итоговая картина релиза
|
Формат |
Архитектуры |
Описание |
|
|
x86_64, armhf, arm64 |
Универсальная ручная установка |
|
|
x86_64, armhf, arm64 |
Ubuntu, Debian, Raspberry Pi |
|
|
x86_64 |
Fedora, RHEL, CentOS, openSUSE |
|
Docker |
Любая (универсально) |
Без установки, CI/CD, DevOps |
🐳 Docker: зачем он понадобился и как встроился в сборку
Изначально идея добавить Docker-образ DotPlus не стояла на первом месте. Основной упор делался на нативные бинарники и установочные пакеты. Однако в процессе развития проекта стало ясно: Docker — это не просто «в довесок», а необходимый инструмент, без которого:
-
невозможно обеспечить стабильную кросс-сборку в CI;
-
нельзя удобно использовать CLI в автоматических сценариях;
-
сложно дистрибутировать DotPlus в окружениях DevOps и серверов.
🔍 Зачем вообще нужен Docker?
Основные причины интеграции Docker:
-
✅ Надежная изоляция окружения в CI/CD
Дажеcrossработает внутри Docker-контейнеров. Если ты не контролируешь окружение сборки (например, на GitHub Actions), Docker становится стандартом. -
✅ Упрощённый запуск без установки
CLI-версия DotPlus можно использовать прямо из Docker без установки бинарников, зависимостей и пакетов. Это особенно ценно для DevOps и автоматизации. -
✅ Платформа-агностичный дистрибутив
Один образ — один результат. Его поведение одинаково в любой системе, будь то Windows, Linux или macOS (с установленным Docker). -
✅ Разделение GUI и CLI
Docker используется только для CLI. Это упрощает образ, делает его минимальным и не тянет GUI-библиотеки.
🛠 Структура Dockerfile
В проекте используется Dockerfile.cli:
FROM debian:bookworm-slim COPY dotplus /usr/local/bin/dotplus ENTRYPOINT ["dotplus"]
Это минимальный образ (на базе slim-дистрибутива Debian), в который помещается только собранный бинарник dotplus. Никаких дополнительных зависимостей, библиотек или окружения не требуется.
⚙️ Интеграция в CI
Сборка Docker-образа происходит автоматически, после компиляции CLI:
- name: Build Docker image run: | docker build -f docker/Dockerfile.cli -t ghcr.io/nigdanil/dotplus:latest . docker push ghcr.io/nigdanil/dotplus:latest
Docker-образ публикуется в Docker Hub, откуда его может скачать любой пользователь:
docker pull nigdanil/dotplus-cli:latest
🚀 Как использовать Docker-версию DotPlus
Пример запуска CLI внутри Docker:
docker run --rm -v $(pwd):/out ghcr.io/nigdanil/dotplus:latest \ --text "Docker test" --format qrcode --output /out/code.png
Объяснение:
-
--rm— удаляет контейнер после завершения -
-v $(pwd):/out— монтирует текущую папку внутрь контейнера для вывода результата -
--text,--format,--output— аргументы CLI DotPlus
Таким образом, можно использовать DotPlus в любом CI, на сервере, на macOS или даже в WSL — не устанавливая ничего, кроме Docker.
💻 Запуск DotPlus через Docker на Windows (.bat-файлы)
👉 Для пользователей Windows подготовлены удобные .bat-скрипты, которые вызывают CLI DotPlus внутри Docker-контейнера. Это позволяет запускать генерацию QR и штрихкодов без установки зависимостей.
📄 run-qr.bat — генерация QR-кодов
@echo off REM Генерация QR-кодов из CSV через Docker docker run --rm -v "%cd%\examples:/examples" nigdanil/dotplus-cli:1.0.0 ^ --mode qr ^ --csv "/examples/magnit/data/qr/magnit.csv" ^ --logo "/examples/magnit/logo/v1.png" ^ --output "/examples/magnit/img/qr" ^ --cols 3 ^ --rows 3 ^ --qr-size 150 ^ --font-size 24 ^ --font-color "#000000" pause
📄 run-barcode.bat — генерация EAN-13 штрихкодов
@echo off REM Генерация штрихкодов EAN-13 из CSV через Docker docker run --rm -v "%cd%\examples:/examples" nigdanil/dotplus-cli:1.0.0 ^ --mode barcode ^ --csv "/examples/magnit/data/barcode/magnit-barcodes-EAN-13.csv" ^ --output "/examples/magnit/img/barcode" ^ --barcode-type EAN-13 ^ --cols 3 ^ --rows 4 ^ --width 300 ^ --height 100 ^ --font-size 22 ^ --label-height 40 ^ --offset-y 10 ^ --spacing-x 20 ^ --spacing-y 20 pause
📂 Структура проекта для скриптов
D:\dotplus-windows\ ├── examples\ ├── run-qr.bat └── run-barcode.bat
📌 Скрипты монтируют папку examples внутрь контейнера и сохраняют результат в удобное место. Всё, что нужно — это установленный Docker.
✅ Почему это удобно?
-
Не нужно устанавливать
Rust, зависимости или самdotplus -
Работает на любой машине с Docker
-
Можно интегрировать в автоматизацию, скрипты, CI/CD
📌 Что удалось благодаря Docker
|
Проблема |
Решение через Docker |
|
Кросс-сборка в CI |
|
|
Использование без установки |
Образ с CLI доступен публично |
|
Интеграция в shell-скрипты и пайплайны |
CLI можно вызывать из любого скрипта |
|
Минимизация зависимости |
Образ содержит только |
✅ Вывод: Docker стал неотъемлемой частью инфраструктуры DotPlus. Он используется и в процессе сборки, и как самостоятельный способ запуска CLI. Это позволяет дистрибутировать инструмент в любую среду — будь то сервер, CI/CD или чужой компьютер без установки зависимостей.
📜 Лицензия DotPlus: от исходников к закрытому дистрибутиву
В первой версии DotPlus проект поставлялся с открытым кодом. Однако с релизом стабильных версий и запуском сборок под Linux, стало ясно: пора пересмотреть подход к лицензированию. Причин этому — несколько, и они связаны как с техническими, так и с юридическими и практическими аспектами.
В результате было принято решение:
📌 Перейти на бесплатную, но проприетарную лицензию.
❓ Почему так?
Вот ключевые причины:
-
Минимизация рисков форков и переиспользования бренда
Когда проект становится узнаваемым, велик риск «серых» клонов, которые могут нарушать философию продукта или использовать имя DotPlus без разрешения. -
Снижение нагрузки на поддержку
Когда код открыт, пользователи часто создают собственные сборки, вносят изменения и потом задают вопросы, не относящиеся к официальной версии. -
Защита бизнес-модели и эксклюзивных алгоритмов
DotPlus использует внутренние техники вставки логотипов, оптимизации QR, компактного вывода и т. д. Их защита — ключ к качеству конечного продукта. -
Фокус на стабильных бинарниках, а не на доработках со стороны сообщества
Вся сборка и дистрибуция централизованы — это позволяет гарантировать качество и одинаковое поведение на всех системах.
✅ Что разрешено по новой лицензии?
-
🔓 Бесплатное использование для любых целей — как в личных, так и в коммерческих проектах
-
📦 Распространение неизменённых бинарников
-
👥 Использование в организациях, автоматизации, CI/CD и т. п.
❌ Что запрещено?
-
🚫 Изучение, анализ, декомпиляция и модификация бинарников
-
🚫 Распространение модифицированных версий
-
🚫 Попытки восстановить или раскрыть исходный код
📁 Как распространяется DotPlus сейчас?
-
✅ Только в виде бинарников (
.exe,.deb,.rpm,.tar.gz) -
✅ Через официальный GitHub Releases и Docker Registry
📄 Лицензионное соглашение (фрагмент)
Тип лицензии: Бесплатное ПО (проприетарное)
Исходный код: не распространяется
Использование: разрешено для личного и коммерческого применения
Обратная разработка: строго запрещена
Распространение: допустимо только в виде неизменённых бинарников с включением лицензионного соглашения
Авторские права: исходный код и все права на него остаются за автором
⚠️ Почему это всё равно честно?
Несмотря на закрытую лицензию, DotPlus остаётся:
-
полностью бесплатным;
-
стабильным и регулярно обновляемым;
-
совместимым с Linux, Windows, Docker;
-
понятным и удобным инструментом, который не требует онлайн-доступа или регистрации.
Более того, пользователь всё ещё получает CLI-инструмент, GUI-приложение и все опции (включая CSV, логотипы, экспорт) без ограничений функциональности.
✅ Вывод: лицензия DotPlus теперь закрытая, но прозрачная. Программа остаётся бесплатной, распространяется в виде готовых бинарников и полностью пригодна для реального применения — без страха перед юридическими подводными камнями.
📈 Итоги и планы развития DotPlus
DotPlus прошёл большой путь от простой Windows-программы до полноценного кроссплатформенного инструмента с поддержкой CLI, GUI, Docker и релизами под Linux. Этот этап развития был посвящён тому, чтобы сделать проект устойчивым, универсальным и легко доставляемым в любой среде.
✅ Что реализовано
|
Возможность |
Статус |
Комментарий |
|
🖥 GUI для Windows и Linux |
✅ Готово |
На базе |
|
🧾 CLI-интерфейс |
✅ Готово |
Генерация QR/штрихкодов через параметры |
|
📦 DEB и RPM-пакеты |
✅ В релизах |
Для всех популярных дистрибутивов |
|
🐳 Docker-образ |
✅ Опубликован |
Поддержка запуска без установки |
|
🔄 CI/CD-сборка и релизы |
✅ Автоматизировано |
Публикация в GitHub Releases + GHCR |
|
🔐 Проприетарная лицензия |
✅ Введена |
Бесплатно, без исходников, с разрешением на использование |
🛠 Технические особенности
-
Используется
crossдля мультиархитектурной сборки (x86_64, ARMv7, AArch64) -
Автоматическая генерация
.debи.rpmчерез скриптtools/generate.sh -
CI/CD на GitHub Actions, один YAML управляет всем пайплайном
-
Распространение Docker-образа через Docker Hub:
docker pull nigdanil/dotplus-cli:latest
🔮 Что в планах?
Вот направления, над которыми планируется работать в следующих релизах:
|
План |
Статус |
Комментарий |
|
📄 Экспорт в PDF и SVG |
🔜 В процессе |
Для векторной печати и типографий |
|
🌐 Web-версия на WASM |
🔜 Исследуется |
Возможность запуска в браузере без сервера |
|
📄 Поддержка больших CSV |
🔜 Планируется |
Пакетная генерация с логами и ошибками |
|
🔄 Автообновление для GUI |
🔜 Будет |
Особенно для Windows-версии |
|
⚙️ Расширение CLI |
🔜 Постепенно |
Больше форматов, управление шаблонами |
|
🔔 Интеграция уведомлений |
🔜 Через |
Пока опциональная фича |
|
|
|
|
🤝 Обратная связь и участие
Если вам не хватает какой-то функции, формат не поддерживается, или вы хотите предложить идею — открывайте issue на GitHub:
📌 https://github.com/nigdanil/dotplus
✅ Финальный вывод
DotPlus стал стабильным, мощным и универсальным инструментом для генерации QR и штрихкодов.
Поддержка разных архитектур, нативные пакеты, Docker и офлайн-режим делают его отличным выбором для всех — от домашних пользователей до CI-инфраструктур.
Программа продолжит развиваться. Спасибо всем, кто использует, тестирует и даёт обратную связь.
ссылка на оригинал статьи https://habr.com/ru/articles/924976/
Добавить комментарий