跳到主要内容

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 更约定俗成。

相关链接