编写 Go 项目的 Makefile 不完全指南

1,590 阅读1分钟

Makefile 的主要的作用是简化构建难度,以及减少 “祖传” 代码。

我也看了很多关于 Go 的 Makefile 文章,但是大部分都是如何用,以及贴上一个特别简单的例子,想要放到 实际项目中使用还相差的很远,所以决定自己写一份自认为可以覆盖 Go 项目的大部分场景的 Makefile 通用 模版。

覆盖了以下场景:

  • 多程序编译
  • 交叉编译
  • 基于 docker 编译
  • 基于 pakcage 的覆盖率单元测试
  • 清理编译环境

模版

既然是模版所以肯定会涉及到参数的修改,模版中可以修改的变量都为大写字母,意思也很明确这里就不多介绍了。

VERSION ?= v1.0.0
BUILD_DIR ?= build

PKG_NAME = github.com/yakumioto/go-makefile-example
IMAGE_NAME = yakumioto/go-makefile-example-

CGO_ENABLED ?= $(shell go env CGO_ENABLED)
GOARCH ?= $(shell go env GOARCH)
GOOS ?= $(shell go env GOOS)
GO_LDFLAGS ?= -s -w -extldflags \"-static\"

override timestamp = $(shell date '+%s')
override app = $(filter-out $@,$(MAKECMDGOALS))
override package = $(PKG_NAME)/$(filter-out $@,$(MAKECMDGOALS))
override output_build_dir = $(BUILD_DIR)/apps/$(GOOS)
override output_test_dir = $(BUILD_DIR)/tests

.PHONY : build docker-build test clean

%:
	@:

build:
	@echo "Building $(app) app..."
	@mkdir -p $(output_build_dir)
	CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(output_build_dir)/$(app) -ldflags '$(GO_LDFLAGS)' $(PKG_NAME)/cmd/$(app)

docker-build:
	@echo "Building $(app) app in docker..."

	@echo "Building vendor..."
	@go mod vendor

	@echo "Building image..."
	@docker build \
           		--build-arg command="CGO_ENABLED=$(CGO_ENABLED) go build -o /app -ldflags '$(GO_LDFLAGS)' $(PKG_NAME)/cmd/$(app)" \
           		-t $(IMAGE_NAME)$(app):$(VERSION) -f images/$(app)/Dockerfile .

test:
	@echo "Testing $(package) ..."
	@mkdir -p $(output_test_dir)
	go test -coverprofile=$(output_test_dir)/$(timestamp).out $(package)

clean:
	@echo "Cleaning..."
	@rm -rf build/*
	@rm -rf vendor

使用

github.com/yakumioto/m… 为例,系统为 macOS

makefile-go-eample
├── build
├── cmd
│   └── add
├── images
│   └── add
└── internal
    └── utils

命令栗子:

  • make build add
  • make docker-build add
  • make build add GOOS=linux
  • make docker-build add GOOS=linux GOARCH=386
  • make test internal/utils
  • make clean

当然很多命令都可以追加参数,以达到想要的目的,不过我觉得已经覆盖大部分场景了。

参考