# SyncLive — Makefile # 对标 SyncTV 的 SFU 分流服务(SRS 主干 + Cloudflare/CND 分发) SHELL := /bin/bash .DEFAULT_GOAL := help # ── 变量 ────────────────────────────────────────────── BIN := server CMD := ./cmd/server WEB_DIR := web STATIC_DIR := internal/server/static PROTO_DIR := api GEN_DIR := gen COMPOSE_FILE := deploy/docker-compose.yml GO ?= go PNPM ?= pnpm # 从 .env 注入端口(若存在),否则用默认值 -include .env export HTTP_PORT ?= 8088 GRPC_PORT ?= 9090 GOFLAGS ?= -trimpath LDFLAGS ?= -s -w CGO_ENABLED ?= 1 # ── 帮助 ────────────────────────────────────────────── .PHONY: help help: ## 显示可用目标 @echo "SyncLive — make 帮助" @echo "" @echo "Usage: make [target]" @echo "" @grep -h -E '^[a-zA-Z0-9_.-]+:.*?## ' $(MAKEFILE_LIST) | awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-18s\033[0m %s\n",$$1,$$2}' @echo "" @echo "示例:" @echo " make env # 首次初始化 .env" @echo " make srs-up # 启动本地 SRS 主干" @echo " make dev # 热启动控制面 (go run)" @echo " make build # 前端 + 后端完整构建" @echo " make test check # 质量门禁" # ── 环境 ────────────────────────────────────────────── .PHONY: env env: ## 若无 .env 则从 .env.example 复制 @if [ -f .env ]; then \ echo ".env 已存在,跳过"; \ else \ cp .env.example .env; \ echo ".env 已从 .env.example 创建,请按需填写 JWT_SECRET / CF_* / CDN_*"; \ fi # ── 依赖安装 ────────────────────────────────────────── .PHONY: install install-go install-web install: install-go install-web ## 安装 Go 与前端依赖 install-go: ## go mod download $(GO) mod download install-web: ## pnpm install (web/) @if ! command -v $(PNPM) >/dev/null 2>&1; then \ echo "error: pnpm 未安装,请先安装 https://pnpm.io/installation"; exit 1; fi cd $(WEB_DIR) && $(PNPM) install # ── 前端 ────────────────────────────────────────────── .PHONY: web web-build web-dev web-typecheck web-preview web-clean web: web-build ## alias: web = web-build web-build: ## 构建前端到 $(STATIC_DIR)(被 Go embed) @if ! command -v $(PNPM) >/dev/null 2>&1; then \ echo "error: pnpm 未安装"; exit 1; fi cd $(WEB_DIR) && $(PNPM) run build @echo "web build -> $(STATIC_DIR)" web-dev: ## 启动 Vite 开发服务器 (5173,反代到 :$(HTTP_PORT)) @if ! command -v $(PNPM) >/dev/null 2>&1; then \ echo "error: pnpm 未安装"; exit 1; fi cd $(WEB_DIR) && $(PNPM) run dev web-typecheck: ## 前端类型检查 cd $(WEB_DIR) && $(PNPM) run typecheck web-preview: ## 预览前端构建产物 cd $(WEB_DIR) && $(PNPM) run preview web-clean: ## 清理前端构建产物与依赖 rm -rf $(WEB_DIR)/node_modules rm -rf $(WEB_DIR)/dist # ── 后端构建 / 运行 ─────────────────────────────────── .PHONY: build build-go build-all run dev build: web-build build-go ## 完整构建:前端 + Go 二进制 build-go: ## 仅构建 Go 二进制 -> ./$(BIN)(含前端 embed) CGO_ENABLED=$(CGO_ENABLED) $(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BIN) $(CMD) @echo "built -> ./$(BIN) (HTTP :$(HTTP_PORT) gRPC :$(GRPC_PORT))" build-all: build ## alias: build-all = build run: ## go run ./cmd/server(不等前端构建) $(GO) run $(CMD) dev: ## 开发态运行(等价于 run,打印后端链路信息) @echo "starting sync-live (HTTP :$(HTTP_PORT) gRPC :$(GRPC_PORT)) ..." $(GO) run $(CMD) # ── 协议 / 代码生成 ─────────────────────────────────── .PHONY: proto gen buf proto: gen ## alias: proto = gen gen: ## buf generate api(需 buf CLI,已含 go/go-grpc 插件) @if command -v buf >/dev/null 2>&1; then \ buf generate $(PROTO_DIR); \ echo "proto generated -> $(GEN_DIR)/"; \ elif command -v docker >/dev/null 2>&1; then \ echo "buf 未安装,改用 docker (bufbuild/buf) ..."; \ docker run --rm -v "$$(pwd):/workspace" -w /workspace bufbuild/buf generate $(PROTO_DIR); \ else \ echo "error: 未找到 buf,请安装 https://buf.build/docs/installation"; exit 1; fi buf: gen ## alias: buf = gen # ── 质量门禁 ────────────────────────────────────────── .PHONY: fmt vet lint test tidy check fmt: ## go fmt ./... $(GO) fmt ./... vet: ## go vet ./... $(GO) vet ./... lint: ## golangci-lint(若未安装则回退到 go vet) @if command -v golangci-lint >/dev/null 2>&1; then \ golangci-lint run ./...; \ else \ echo "golangci-lint 未安装,跳过。安装: https://golangci-lint.run/welcome/install/"; \ echo "回退到 go vet ..."; \ $(GO) vet ./...; \ fi test: ## go test ./...(含 -count=1) $(GO) test ./... -count=1 tidy: ## go mod tidy $(GO) mod tidy check: fmt vet test ## 质量门禁:fmt + vet + test # ── SRS / Docker ────────────────────────────────────── .PHONY: srs-up srs-down srs-logs srs-restart compose-up compose-down docker-up docker-down srs-up: ## 启动 SRS 主干(deploy/docker-compose.yml) @SRS_CANDIDATE=$${SRS_CANDIDATE:-127.0.0.1} docker compose -f $(COMPOSE_FILE) up -d srs @docker compose -f $(COMPOSE_FILE) ps srs-down: ## 停止 SRS docker compose -f $(COMPOSE_FILE) down srs-logs: ## 查看 SRS 日志 docker compose -f $(COMPOSE_FILE) logs -f srs srs-restart: ## 重启 SRS docker compose -f $(COMPOSE_FILE) restart srs compose-up: srs-up ## alias: compose-up = srs-up compose-down: srs-down ## alias: compose-down = srs-down docker-up: srs-up ## alias: docker-up = srs-up docker-down: srs-down ## alias: docker-down = srs-down # ── 清理 ────────────────────────────────────────────── .PHONY: clean clean-all clean: ## 清理 Go 构建产物与缓存(二进制、/tmp/sync-live) rm -f $(BIN) rm -rf /tmp/sync-live $(GO) clean -cache -testcache 2>/dev/null || true @echo "clean done." clean-all: clean web-clean ## 深度清理:clean + 前端产物/依赖 rm -rf $(STATIC_DIR)/assets @echo "clean-all done."