You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
tetris/Makefile

331 lines
14 KiB

# Tetris Game - 统一构建系统
# 支持 Windows 和 macOS 应用打包,统一使用 dist 目录
# 基础配置
BINARY_NAME := tetris
APP_NAME := TetrisGame
VERSION := 1.0
BUILD_TIME := $(shell date '+%Y-%m-%d %H:%M:%S')
GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
# 目录配置
DIST_DIR := dist
ASSETS_DIR := assets
BUILD_TEMP := .build_temp
# Go 构建标志
GO_LDFLAGS := -ldflags "-s -w"
GO_LDFLAGS_GUI := -ldflags "-s -w -H windowsgui"
# 平台特定配置
WINDOWS_DIR := $(DIST_DIR)/windows
MACOS_DIR := $(DIST_DIR)/macos
LINUX_DIR := $(DIST_DIR)/linux
# 版本文件名
WINDOWS_ZIP := $(APP_NAME)-Windows-v$(VERSION).zip
MACOS_DMG := $(APP_NAME)-macOS-v$(VERSION).dmg
LINUX_TAR := $(APP_NAME)-Linux-v$(VERSION).tar.gz
# 颜色输出
BLUE := \033[34m
GREEN := \033[32m
YELLOW := \033[33m
RED := \033[31m
RESET := \033[0m
.DEFAULT_GOAL := help
# 帮助信息
.PHONY: help
help: ## 显示帮助信息
@echo "$(BLUE)🎮 Tetris Game 构建系统$(RESET)"
@echo ""
@echo "$(GREEN)基础命令:$(RESET)"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " $(YELLOW)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
@echo ""
@echo "$(GREEN)示例:$(RESET)"
@echo " make all # 构建所有平台"
@echo " make windows # 仅构建 Windows 版本"
@echo " make macos # 仅构建 macOS 版本"
@echo " make clean # 清理所有构建文件"
# 信息显示
.PHONY: info
info: ## 显示构建信息
@echo "$(BLUE)📋 构建信息$(RESET)"
@echo " 应用名称: $(APP_NAME)"
@echo " 版本: v$(VERSION)"
@echo " 构建时间: $(BUILD_TIME)"
@echo " Git 提交: $(GIT_COMMIT)"
@echo " Go 版本: $(shell go version)"
@echo " 当前平台: $(shell go env GOOS)/$(shell go env GOARCH)"
@echo " 分发目录: $(DIST_DIR)/"
# 环境检查
.PHONY: check-env
check-env: ## 检查构建环境
@echo "$(BLUE)🔍 环境检查$(RESET)"
@go version >/dev/null 2>&1 || (echo "$(RED)❌ Go 未安装$(RESET)" && exit 1)
@echo "$(GREEN)✅ Go 环境正常$(RESET)"
@[ -d "$(ASSETS_DIR)" ] || (echo "$(RED)❌ assets 目录缺失$(RESET)" && exit 1)
@echo "$(GREEN)✅ 资源目录存在$(RESET)"
@[ -f "main.go" ] || (echo "$(RED)❌ main.go 文件缺失$(RESET)" && exit 1)
@echo "$(GREEN)✅ 源代码文件存在$(RESET)"
# 准备目录
.PHONY: prepare
prepare: ## 准备构建目录
@echo "$(BLUE)📁 准备构建目录$(RESET)"
@mkdir -p $(DIST_DIR)
@mkdir -p $(WINDOWS_DIR)
@mkdir -p $(MACOS_DIR)
@mkdir -p $(LINUX_DIR)
@mkdir -p $(BUILD_TEMP)
# 清理
.PHONY: clean
clean: ## 清理构建文件
@echo "$(BLUE)🧹 清理构建文件$(RESET)"
@rm -rf $(DIST_DIR)
@rm -rf $(BUILD_TEMP)
@rm -f *.zip *.dmg *.tar.gz
@rm -f $(BINARY_NAME) $(BINARY_NAME).exe
@rm -rf TetrisGame.app
@echo "$(GREEN)✅ 清理完成$(RESET)"
# Windows 构建
.PHONY: build-windows-binary
build-windows-binary: check-env prepare
@echo "$(BLUE)🪟 构建 Windows 二进制文件$(RESET)"
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build $(GO_LDFLAGS_GUI) -o $(BUILD_TEMP)/$(APP_NAME).exe .
@echo "$(GREEN)✅ Windows 二进制文件构建完成$(RESET)"
.PHONY: create-windows-startup-script
create-windows-startup-script:
@echo "创建 Windows 启动脚本..."
@echo '@echo off' > $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'chcp 65001 >nul' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo 🎮 正在启动 Tetris Game...' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo.' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo 🎯 游戏控制:' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo ←→ 左右移动' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo ↑ 旋转方块' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo ↓ 快速下降' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo 空格 瞬间下降' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo L 切换中英文' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo 'echo.' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
@echo '"%~dp0$(APP_NAME).exe"' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/启动游戏.bat
.PHONY: create-windows-docs
create-windows-docs:
@echo "创建 Windows 说明文档..."
@echo '🎮 Tetris Game - Windows Version v1.0' > $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '📥 Installation: This is a portable version, no installation required.' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '🚀 How to Start: Double-click TetrisGame.exe or 启动游戏.bat' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '🎯 Game Controls: ←→ Move, ↑ Rotate, ↓ Soft drop, Space Hard drop, L Language' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '🔧 System Requirements: Windows 10/11 (64-bit)' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
@echo '© 2025 Tetris Game. All rights reserved.' >> $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/README.txt
.PHONY: package-windows
package-windows: build-windows-binary
@echo "$(BLUE)📦 打包 Windows 应用$(RESET)"
# 创建 Windows 应用目录
@rm -rf $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)
@mkdir -p $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)
# 复制主程序文件
@cp $(BUILD_TEMP)/$(APP_NAME).exe $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/
# 复制资源文件
@cp -r $(ASSETS_DIR) $(WINDOWS_DIR)/$(APP_NAME)-Windows-v$(VERSION)/
# 创建启动脚本和文档
@$(MAKE) create-windows-startup-script
@$(MAKE) create-windows-docs
# 创建压缩包
@cd $(WINDOWS_DIR) && zip -r ../$(WINDOWS_ZIP) $(APP_NAME)-Windows-v$(VERSION)/
@echo "$(GREEN)✅ Windows 应用打包完成: $(DIST_DIR)/$(WINDOWS_ZIP)$(RESET)"
# macOS 构建
.PHONY: build-macos-binary
build-macos-binary: check-env prepare
@echo "$(BLUE)🍎 构建 macOS 二进制文件$(RESET)"
go build $(GO_LDFLAGS) -o $(BUILD_TEMP)/$(BINARY_NAME) .
@echo "$(GREEN)✅ macOS 二进制文件构建完成$(RESET)"
.PHONY: create-macos-plist
create-macos-plist:
@echo "创建 macOS Info.plist..."
@echo '<?xml version="1.0" encoding="UTF-8"?>' > $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '<plist version="1.0">' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '<dict>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleDisplayName</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>俄罗斯方块</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleExecutable</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>$(BINARY_NAME)</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleIdentifier</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>com.tetrisgame.app</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleName</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>$(APP_NAME)</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleShortVersionString</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>$(VERSION)</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>CFBundleIconFile</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>app</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <key>LSApplicationCategoryType</key>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo ' <string>public.app-category.games</string>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '</dict>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
@echo '</plist>' >> $(MACOS_DIR)/$(APP_NAME).app/Contents/Info.plist
.PHONY: create-dmg
create-dmg:
@echo "创建 DMG 文件..."
@DMG_SIZE="50m" && \
TEMP_DMG="$(BUILD_TEMP)/temp_$(MACOS_DMG)" && \
MOUNT_POINT="$(BUILD_TEMP)/dmg_mount" && \
rm -rf $$MOUNT_POINT && \
mkdir -p $$MOUNT_POINT && \
hdiutil create -size $$DMG_SIZE -fs HFS+ -volname "Tetris Game" $$TEMP_DMG && \
hdiutil attach $$TEMP_DMG -mountpoint $$MOUNT_POINT && \
cp -R $(MACOS_DIR)/$(APP_NAME).app $$MOUNT_POINT/ && \
ln -s /Applications $$MOUNT_POINT/Applications && \
hdiutil detach $$MOUNT_POINT && \
hdiutil convert $$TEMP_DMG -format UDZO -o $(DIST_DIR)/$(MACOS_DMG) && \
rm -f $$TEMP_DMG
.PHONY: package-macos
package-macos: build-macos-binary
@echo "$(BLUE)📦 打包 macOS 应用$(RESET)"
# 创建 .app 包结构
@rm -rf $(MACOS_DIR)/$(APP_NAME).app
@mkdir -p $(MACOS_DIR)/$(APP_NAME).app/Contents/MacOS
@mkdir -p $(MACOS_DIR)/$(APP_NAME).app/Contents/Resources
# 复制可执行文件
@cp $(BUILD_TEMP)/$(BINARY_NAME) $(MACOS_DIR)/$(APP_NAME).app/Contents/MacOS/
@chmod +x $(MACOS_DIR)/$(APP_NAME).app/Contents/MacOS/$(BINARY_NAME)
# 复制资源文件
@cp -r $(ASSETS_DIR) $(MACOS_DIR)/$(APP_NAME).app/Contents/Resources/
# 创建 Info.plist
@$(MAKE) create-macos-plist
# 复制应用图标
@if [ -f "$(ASSETS_DIR)/icons/app.icns" ]; then \
cp "$(ASSETS_DIR)/icons/app.icns" $(MACOS_DIR)/$(APP_NAME).app/Contents/Resources/; \
echo "$(GREEN)✅ 已复制应用图标 app.icns$(RESET)"; \
else \
echo "$(YELLOW) 图标文件 $(ASSETS_DIR)/icons/app.icns 不存在$(RESET)"; \
fi
# 创建 DMG
@$(MAKE) create-dmg
@echo "$(GREEN)✅ macOS 应用打包完成: $(DIST_DIR)/$(MACOS_DMG)$(RESET)"
# Linux 构建
.PHONY: build-linux-binary
build-linux-binary: check-env prepare
@echo "$(BLUE)🐧 构建 Linux 二进制文件$(RESET)"
@echo "$(YELLOW) 注意: Linux 交叉编译需要 CGO 支持,建议在 Linux 系统上构建$(RESET)"
@if [ "$$(go env GOOS)" = "linux" ]; then \
go build $(GO_LDFLAGS) -o $(BUILD_TEMP)/$(BINARY_NAME)_linux .; \
else \
echo "$(YELLOW) 当前不在 Linux 系统,跳过 Linux 构建$(RESET)"; \
mkdir -p $(BUILD_TEMP); \
echo "# Linux 构建需要在 Linux 系统上进行" > $(BUILD_TEMP)/$(BINARY_NAME)_linux.txt; \
fi
@echo "$(GREEN)✅ Linux 二进制文件构建完成$(RESET)"
.PHONY: package-linux
package-linux: build-linux-binary
@echo "$(BLUE)📦 打包 Linux 应用$(RESET)"
@if [ "$$(go env GOOS)" = "linux" ] && [ -f "$(BUILD_TEMP)/$(BINARY_NAME)_linux" ]; then \
echo "正在打包 Linux 应用..."; \
rm -rf $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION); \
mkdir -p $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION); \
cp $(BUILD_TEMP)/$(BINARY_NAME)_linux $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/$(BINARY_NAME); \
chmod +x $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/$(BINARY_NAME); \
cp -r $(ASSETS_DIR) $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/; \
echo '#!/bin/bash' > $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
echo 'echo "🎮 Starting Tetris Game..."' >> $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
echo 'cd "$$(dirname "$$0")"' >> $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
echo './$(BINARY_NAME)' >> $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
chmod +x $(LINUX_DIR)/$(APP_NAME)-Linux-v$(VERSION)/start_game.sh; \
cd $(LINUX_DIR) && tar -czf ../$(LINUX_TAR) $(APP_NAME)-Linux-v$(VERSION)/; \
echo "$(GREEN)✅ Linux 应用打包完成: $(DIST_DIR)/$(LINUX_TAR)$(RESET)"; \
else \
echo "$(YELLOW) 跳过 Linux 打包(需要在 Linux 系统上构建)$(RESET)"; \
mkdir -p $(LINUX_DIR); \
echo "# Linux 版本需要在 Linux 系统上构建" > $(LINUX_DIR)/README.txt; \
echo "$(YELLOW) Linux 版本跳过$(RESET)"; \
fi
# 主要构建目标
.PHONY: windows
windows: package-windows ## 构建 Windows 版本
.PHONY: macos
macos: package-macos ## 构建 macOS 版本
.PHONY: linux
linux: package-linux ## 构建 Linux 版本
.PHONY: all
all: clean windows macos ## 构建所有支持的平台版本
@if [ "$$(go env GOOS)" = "linux" ]; then \
$(MAKE) linux; \
else \
echo "$(YELLOW) 当前平台不支持 Linux 交叉编译,跳过 Linux 构建$(RESET)"; \
fi
@echo ""
@echo "$(GREEN)🎉 所有平台构建完成!$(RESET)"
@echo ""
@echo "$(BLUE)📋 构建结果:$(RESET)"
@ls -lh $(DIST_DIR)/*.zip $(DIST_DIR)/*.dmg $(DIST_DIR)/*.tar.gz 2>/dev/null || true
# 验证和测试
.PHONY: verify
verify: ## 验证构建结果
@echo "$(BLUE)🔍 验证构建结果$(RESET)"
@echo ""
@echo "$(GREEN)构建文件:$(RESET)"
@ls -lh $(DIST_DIR)/ 2>/dev/null || echo "无构建文件"
@echo ""
@if [ -f "$(DIST_DIR)/$(WINDOWS_ZIP)" ]; then \
echo "$(GREEN)✅ Windows 版本: $(WINDOWS_ZIP)$(RESET)"; \
unzip -l $(DIST_DIR)/$(WINDOWS_ZIP) | head -10; \
fi
@if [ -f "$(DIST_DIR)/$(MACOS_DMG)" ]; then \
echo "$(GREEN)✅ macOS 版本: $(MACOS_DMG)$(RESET)"; \
fi
@if [ -f "$(DIST_DIR)/$(LINUX_TAR)" ]; then \
echo "$(GREEN)✅ Linux 版本: $(LINUX_TAR)$(RESET)"; \
fi
# 开发相关
.PHONY: run
run: ## 运行游戏(开发模式)
@echo "$(BLUE)🎮 启动游戏$(RESET)"
go run .
.PHONY: test
test: ## 运行测试
@echo "$(BLUE)🧪 运行测试$(RESET)"
go test -v ./...
.PHONY: deps
deps: ## 下载依赖
@echo "$(BLUE)📦 下载依赖$(RESET)"
go mod download
go mod tidy