.PHONY: all clean build-mac build-windows build-linux build-linux-musl package help quick package-single setup icons favicon windows-icon # Название проекта PROJECT_NAME := ae_anons RELEASE_DIR := target/release BINARIES_DIR := releases VERSION := $(shell grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/') # Определение текущей ОС UNAME_S := $(shell uname -s) UNAME_M := $(shell uname -m) # Цвета для вывода GREEN := \033[0;32m RED := \033[0;31m YELLOW := \033[1;33m BLUE := \033[0;34m CYAN := \033[0;36m MAGENTA := \033[0;35m BOLD := \033[1m NC := \033[0m # Файл для хранения времени сборки TIMING_FILE := .build_timing # Определение команды ImageMagick (v6 = convert, v7 = magick) IMAGEMAGICK := $(shell command -v magick 2>/dev/null || command -v convert 2>/dev/null || echo "false") # Параметры Font Awesome FONTAWESOME_VERSION := 6.4.0 FONTAWESOME_CSS_URL := https://cdnjs.cloudflare.com/ajax/libs/font-awesome/$(FONTAWESOME_VERSION)/css/all.min.css FONTAWESOME_FONTS_URL := https://cdnjs.cloudflare.com/ajax/libs/font-awesome/$(FONTAWESOME_VERSION)/webfonts help: @echo "$(BOLD)$(CYAN)AE Anons - Makefile команды$(NC)" @echo "" @echo "$(GREEN)Сборка под конкретную платформу:$(NC)" @echo " make build-mac - Собрать для macOS (Apple Silicon)" @echo " make build-windows - Собрать для Windows x86_64" @echo " make build-linux - Собрать для Linux x86_64 (GNU)" @echo " make build-linux-musl - Собрать для Linux x86_64 (musl static)" @echo "" @echo "$(GREEN)Быстрая сборка:$(NC)" @echo " make quick - Собрать под текущую платформу с упаковкой" @echo " make quick-release - Собрать под текущую платформу (release, без упаковки)" @echo "" @echo "$(GREEN)Полная сборка:$(NC)" @echo " make build-all - Собрать для всех платформ" @echo " make package - Создать пакеты для всех платформ" @echo " make package-single - Создать пакет для текущей платформы" @echo "" @echo "$(GREEN)Подготовка ресурсов:$(NC)" @echo " make setup - Загрузить и подготовить все статические ресурсы" @echo "" @echo "$(GREEN)Очистка:$(NC)" @echo " make clean - Очистить все сборки" @echo " make clean-timing - Очистить файл с временами сборки" # ============================================ # ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ # ============================================ define copy_common_files @cp .env.example $(1)/ 2>/dev/null || true @cp README.md $(1)/ 2>/dev/null || true @if [ -f LICENSE ]; then cp LICENSE $(1)/; else echo "$(YELLOW)⚠️ LICENSE не найден, пропускаем$(NC)"; fi endef define measure_time @start=$$(date +%s); \ $(2); \ end=$$(date +%s); \ duration=$$((end - start)); \ echo "$(1): $$duration сек" >> $(TIMING_FILE); \ if [ $$duration -ge 60 ]; then \ min=$$((duration / 60)); \ sec=$$((duration % 60)); \ echo "$(GREEN)✓ $(1) завершён за $${min}m $${sec}s$(NC)"; \ else \ echo "$(GREEN)✓ $(1) завершён за $${duration}s$(NC)"; \ fi endef define print_timing_summary @echo "" @echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)" @echo "$(BOLD)$(CYAN) ВРЕМЯ СБОРКИ $(NC)" @echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)" @if [ -f $(TIMING_FILE) ]; then \ total=0; \ while IFS=':' read -r platform duration; do \ sec=$$(echo $$duration | sed 's/ сек//'); \ total=$$((total + sec)); \ printf "$(YELLOW)%-25s$(NC) : $(GREEN)%5d сек$(NC)\n" "$$platform" "$$sec"; \ done < $(TIMING_FILE); \ echo "$(BOLD)$(CYAN)───────────────────────────────────────────────────────────────$(NC)"; \ printf "$(BOLD)$(MAGENTA)%-25s$(NC) : $(BOLD)$(GREEN)%5d сек$(NC) (%.2f мин)\n" "ВСЕГО" "$$total" "$$(echo "scale=2; $$total/60" | bc 2>/dev/null || echo "$$total/60" | awk '{printf "%.2f", $$1/60}')"; \ else \ echo "$(YELLOW)Нет данных о времени сборки$(NC)"; \ fi @echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)" @rm -f $(TIMING_FILE) endef # ============================================ # ПОДГОТОВКА СТАТИЧЕСКИХ РЕСУРСОВ # ============================================ setup: setup-fontawesome icons @echo "$(GREEN)✅ Все статические ресурсы подготовлены$(NC)" # Скачивает и подготавливает Font Awesome, если его ещё нет setup-fontawesome: @echo "$(GREEN)📦 Проверка Font Awesome...$(NC)" @if [ ! -f src/static/fontawesome/all.min.css ]; then \ echo "$(YELLOW) Скачивание all.min.css и шрифтов...$(NC)"; \ mkdir -p src/static/fontawesome/webfonts; \ curl -sL -o src/static/fontawesome/all.min.css $(FONTAWESOME_CSS_URL); \ curl -sL -o src/static/fontawesome/webfonts/fa-solid-900.woff2 $(FONTAWESOME_FONTS_URL)/fa-solid-900.woff2; \ curl -sL -o src/static/fontawesome/webfonts/fa-regular-400.woff2 $(FONTAWESOME_FONTS_URL)/fa-regular-400.woff2; \ curl -sL -o src/static/fontawesome/webfonts/fa-brands-400.woff2 $(FONTAWESOME_FONTS_URL)/fa-brands-400.woff2; \ echo "$(GREEN) ✓ Font Awesome скачан$(NC)"; \ else \ echo "$(GREEN) ✓ Font Awesome уже существует$(NC)"; \ fi @echo "$(GREEN) Исправление путей в all.min.css...$(NC)" @sed -i '' 's|../webfonts/|/static/fontawesome/webfonts/|g' src/static/fontawesome/all.min.css @echo "$(GREEN) ✓ Пути исправлены$(NC)" # Генерация иконок (favicon, .ico, .icns) из логотипа icons: @echo "$(GREEN)🎨 Генерация иконок...$(NC)" @if [ "$(IMAGEMAGICK)" = "false" ]; then \ echo "$(RED)❌ ImageMagick не установлен. Установите: brew install imagemagick$(NC)"; \ exit 1; \ fi # favicon.ico @$(IMAGEMAGICK) assets/logo.png -define icon:auto-resize=48,32,16 src/static/favicon.ico @echo "$(GREEN) ✓ src/static/favicon.ico$(NC)" # Windows .ico @$(IMAGEMAGICK) assets/logo.png -define icon:auto-resize=256,128,64,48,32,16 assets/logo.ico @echo "$(GREEN) ✓ assets/logo.ico$(NC)" # macOS .icns @mkdir -p assets/icon.iconset @sips -z 16 16 assets/logo.png --out assets/icon.iconset/icon_16x16.png 2>/dev/null || true @sips -z 32 32 assets/logo.png --out assets/icon.iconset/icon_16x16@2x.png 2>/dev/null || true @sips -z 32 32 assets/logo.png --out assets/icon.iconset/icon_32x32.png 2>/dev/null || true @sips -z 64 64 assets/logo.png --out assets/icon.iconset/icon_32x32@2x.png 2>/dev/null || true @sips -z 128 128 assets/logo.png --out assets/icon.iconset/icon_128x128.png 2>/dev/null || true @sips -z 256 256 assets/logo.png --out assets/icon.iconset/icon_128x128@2x.png 2>/dev/null || true @sips -z 256 256 assets/logo.png --out assets/icon.iconset/icon_256x256.png 2>/dev/null || true @sips -z 512 512 assets/logo.png --out assets/icon.iconset/icon_256x256@2x.png 2>/dev/null || true @sips -z 512 512 assets/logo.png --out assets/icon.iconset/icon_512x512.png 2>/dev/null || true @iconutil -c icns assets/icon.iconset -o assets/logo.icns 2>/dev/null || true @rm -rf assets/icon.iconset @echo "$(GREEN) ✓ assets/logo.icns$(NC)" # ============================================ # ИКОНКА ДЛЯ WINDOWS .EXE (доп. проверка) # ============================================ windows-icon: @if [ ! -f assets/logo.ico ]; then \ echo "$(YELLOW)logo.ico не найден, запускаю генерацию иконок...$(NC)"; \ $(MAKE) icons; \ fi # ============================================ # ОПРЕДЕЛЕНИЕ ПЛАТФОРМЫ # ============================================ detect-platform: ifeq ($(UNAME_S),Darwin) @echo "$(BLUE)🍎 macOS $(UNAME_M)$(NC)" @$(MAKE) quick-mac else ifeq ($(UNAME_S),Linux) @echo "$(BLUE)🐧 Linux $(UNAME_M)$(NC)" @$(MAKE) quick-linux else ifeq ($(OS),Windows_NT) @echo "$(BLUE)🪟 Windows$(NC)" @$(MAKE) quick-windows else @echo "$(RED)❌ Неизвестная платформа: $(UNAME_S)$(NC)" @exit 1 endif # ============================================ # БЫСТРАЯ СБОРКА (ТЕКУЩАЯ ПЛАТФОРМА) # ============================================ quick: setup detect-platform quick-release: ifeq ($(UNAME_S),Darwin) @echo "$(GREEN)🍎 Сборка для macOS...$(NC)" @time cargo build --release else ifeq ($(UNAME_S),Linux) @echo "$(GREEN)🐧 Сборка для Linux (musl)...$(NC)" @time cargo build --target x86_64-unknown-linux-musl --release else ifeq ($(OS),Windows_NT) @echo "$(GREEN)🪟 Сборка для Windows...$(NC)" @time cargo build --release else @echo "$(RED)❌ Неизвестная платформа$(NC)" @exit 1 endif quick-mac: setup @rm -f $(TIMING_FILE) @$(call measure_time,"🍎 macOS $(UNAME_M)",cargo build --release) @mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M) @cp $(RELEASE_DIR)/$(PROJECT_NAME) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)/ $(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)) @echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)/$(NC)" @$(call print_timing_summary) quick-linux: setup @rm -f $(TIMING_FILE) @$(call measure_time,"🐧 Linux $(UNAME_M)",cargo build --target x86_64-unknown-linux-musl --release) @mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M) @cp target/x86_64-unknown-linux-musl/release/$(PROJECT_NAME) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)/ $(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)) @echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)/$(NC)" @$(call print_timing_summary) quick-windows: setup windows-icon @rm -f $(TIMING_FILE) @if command -v x86_64-w64-mingw32-gcc >/dev/null 2>&1; then \ $(call measure_time,"🪟 Windows x64",cargo build --target x86_64-pc-windows-gnu --release); \ mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64; \ cp target/x86_64-pc-windows-gnu/release/$(PROJECT_NAME).exe $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64/; \ $(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64); \ echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64/$(NC)"; \ $(call print_timing_summary); \ else \ echo "$(RED)❌ Для кросс-компиляции Windows установите mingw-w64:$(NC)"; \ echo " brew install mingw-w64"; \ exit 1; \ fi # ============================================ # СБОРКА ПОД КОНКРЕТНЫЕ ПЛАТФОРМЫ # ============================================ build-mac: setup @echo "$(GREEN)🍎 Сборка для macOS...$(NC)" @time cargo build --release build-windows: setup windows-icon @echo "$(GREEN)🪟 Сборка для Windows x86_64...$(NC)" @time cargo build --target x86_64-pc-windows-gnu --release build-linux: setup @echo "$(GREEN)🐧 Сборка для Linux x86_64 (GNU)...$(NC)" @time cargo build --target x86_64-unknown-linux-gnu --release build-linux-musl: setup @echo "$(GREEN)🐧 Сборка для Linux x86_64 (musl static)...$(NC)" @time cargo build --target x86_64-unknown-linux-musl --release # ============================================ # СБОРКА ВСЕХ ПЛАТФОРМ С ТАЙМИНГОМ # ============================================ build-all: setup @rm -f $(TIMING_FILE) @echo "$(BOLD)$(CYAN)🚀 Сборка для всех платформ...$(NC)" @echo "" @$(call measure_time,"🍎 macOS",cargo build --release) @echo "" @$(call measure_time,"🐧 Linux GNU",cargo build --target x86_64-unknown-linux-gnu --release) @echo "" @$(call measure_time,"🐧 Linux Musl",cargo build --target x86_64-unknown-linux-musl --release) @echo "" @-$(call measure_time,"🪟 Windows",cargo build --target x86_64-pc-windows-gnu --release) @echo "" @$(call print_timing_summary) # ============================================ # УПАКОВКА РЕЛИЗОВ # ============================================ define create_release_package @echo "$(YELLOW)📦 Упаковка для $(1)...$(NC)" @mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1) @cp $(2) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1)/$(3) 2>/dev/null || true $(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1)) @echo "$(GREEN) ✓ $(PROJECT_NAME)-v$(VERSION)-$(1)$(NC)" endef package: build-all @echo "" @echo "$(BOLD)$(CYAN)📦 Создание пакетов...$(NC)" @mkdir -p $(BINARIES_DIR) @$(call create_release_package,macos-arm64,$(RELEASE_DIR)/$(PROJECT_NAME),$(PROJECT_NAME)) @$(call create_release_package,windows-x64,target/x86_64-pc-windows-gnu/release/$(PROJECT_NAME).exe,$(PROJECT_NAME).exe) @$(call create_release_package,linux-gnu,target/x86_64-unknown-linux-gnu/release/$(PROJECT_NAME),$(PROJECT_NAME)) @$(call create_release_package,linux-musl,target/x86_64-unknown-linux-musl/release/$(PROJECT_NAME),$(PROJECT_NAME)) @echo "" @echo "$(GREEN)🗜️ Создание общего архива...$(NC)" @tar -czf $(PROJECT_NAME)-v$(VERSION)-all.tar.gz -C $(BINARIES_DIR) . @echo "$(GREEN)✅ Архив: $(PROJECT_NAME)-v$(VERSION)-all.tar.gz$(NC)" @echo "" @echo "$(BOLD)$(GREEN)🎉 Релиз v$(VERSION) готов!$(NC)" @echo "$(BOLD)📁 Папка: $(BINARIES_DIR)/$(NC)" @ls -lh $(BINARIES_DIR)/ | grep "^d" package-single: detect-platform # ============================================ # ОЧИСТКА # ============================================ clean: @echo "$(RED)🧹 Очистка...$(NC)" cargo clean @rm -rf $(BINARIES_DIR) @rm -f *.tar.gz @rm -f $(TIMING_FILE) @echo "$(GREEN)✅ Очищено$(NC)" clean-timing: @rm -f $(TIMING_FILE) @echo "$(GREEN)✅ Файл с временами сборки удалён$(NC)"