Makefile
问题
Go 项目为什么用 Makefile?常见的 target 有哪些?
答案
为什么用 Makefile
Makefile 统一了开发中的常用操作入口,新人看 Makefile 就知道项目怎么构建、测试、部署。
标准 Makefile
APP_NAME := myapp
VERSION := $(shell git describe --tags --always)
BUILD_TIME := $(shell date -u +%Y%m%dT%H%M%S)
LDFLAGS := -s -w -X main.version=$(VERSION) -X main.buildTime=$(BUILD_TIME)
.PHONY: all build test lint clean docker run
all: lint test build
## 构建
build:
CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o bin/$(APP_NAME) ./cmd/server
## 运行
run:
go run ./cmd/server
## 测试
test:
go test -race -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
## 代码检查
lint:
golangci-lint run ./...
## 代码格式化
fmt:
gofmt -w .
goimports -w .
## 生成代码(proto、mock 等)
generate:
go generate ./...
## Docker
docker:
docker build -t $(APP_NAME):$(VERSION) .
## 清理
clean:
rm -rf bin/ coverage.out
## 数据库迁移
migrate-up:
migrate -path migrations -database "$$DB_DSN" up
migrate-down:
migrate -path migrations -database "$$DB_DSN" down 1
使用
make build # 编译
make test # 测试
make lint # 检查
make docker # 构建镜像
make # 默认执行 all: lint + test + build
常见面试问题
Q1: Makefile vs Shell 脚本?
答案:Makefile 支持依赖关系和增量构建(只重新构建变化的部分),而 Shell 脚本每次都全量执行。另外 Makefile 是事实标准,make build 比 ./scripts/build.sh 更约定俗成。