makefile 是一个文本文件,以下是一个子命令,包含:

  • 名称:支持英文、数字、连字符"-"和下划线 " _"
  • 注释:使用 "#" 表示注释,不支持 /*...*/。推荐写在名称的上一行
  • 命令:任何可在 shell 执行的命令行语句。必须是\t 开头,否则报错 make: Nothing to be done for 'build'.
  • .PHONY:可选,命令声明了 .PHONY,执行时将不会输出具体命令到终端。在一些 CI 工具中可以起到过滤敏感信息的作用。
.PHONY: build
# 编译构建
build:
	go build ./...

变量定义和使用

  • 可直接赋值,也可以执行 shell 赋值。
  • 使用变量的方法是 $(VARIABLE_NAME)。
ENV_GROUP = dev
# 获取最新tag
GIT_TAG=$(shell git tag|grep "v*.[0-9]$$"|sort -r --version-sort|head -n1)
APP_GIT_COMMIT_ID=$(shell git rev-parse --short=8 HEAD)

# 使用变量$(VARIABLE_NAME)
GIT_TAG_COMMIT = $(GIT_TAG)-$(APP_GIT_COMMIT_ID)

多文件

  • 使用 include 引入子文件
include ./scripts/develop.mk
include ./scripts/deploy-local.mk
  • 判断文件存在则引入
#文件存在, 则引入
ifneq ($(wildcard ../scripts/Makefile),)
    include ../scripts/Makefile
endif

if-else判断

可以使用 ifeq ifneq

ifeq ($(NAMESPACE), test-1)
    ENV_GROUP = test-a
else ifeq ($(NAMESPACE), test-2)
    ENV_GROUP = test-a
endif

可以使用在命令中

.PHONY: api
# 由 proto 生成接口层代码
api:
ifneq ($(PROTOC_GEN_GO_VERSION), v1.28.1)
	go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1
else
	echo "ok"
endif

相同变量名,为不同命令导入不同值

使用 export 关键词,为命令传值,可多次传值。


IMAGE_NAME=dockerimg
IMAGE_TAG=dev-1


.PHONY: deploy-test1
# 构建、推送测试环境 1
deploy-test1: export IMAGE_NAME = dockerimg-test
deploy-test1: export IMAGE_TAG = test-1
deploy-test1:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)
	make push

.PHONY: deploy-test2
# 构建、推送测试环境 1
deploy-test2: export IMAGE_NAME = dockerimg-test
deploy-test2: export IMAGE_TAG = test-2
deploy-test2:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)
	make push

从命令行传递变量

上述例子中,定义的变量可以放在shell命令行中,输入完 make 和命令后,追加上变量可以起到传递命令的作用。

IMAGE_NAME=dockerimg
IMAGE_TAG=dev-1

.PHONY: deploy-test
# 构建测试环境,使用方式make deploy-test IMAGE_NAME=img-test-1 IMAGE_TAG=test-1
deploy-test:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)

比如 make deploy-test IMAGE_NAME=img-test-1 IMAGE_TAG=test-1

打印输出所有命令

默认情况下,输入make 执行的是第一个命令,可以通过修改.DEFAULT_GOAL 修改动作。以下是一个 help 命令,输出所有带注释的 make 子命令。

# show help
help:
	@echo ''
	@echo 'Usage:'
	@echo ' make [target]'
	@echo ''
	@echo 'Targets:'
	@awk '/^[a-zA-Z\-\_0-9]+:/ { \
	helpMessage = match(lastLine, /^# (.*)/); \
	    if (helpMessage) { \
	        helpCommand = substr($$1, 0, index($$1, ":")-1); \
	        helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
	        printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
	    } \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)
# 默认 help
.DEFAULT_GOAL := help

输出如下:

$make               

Usage:
 make [target]

Targets:
init                   初始化项目工具和环境
config                 生成配置文件和枚举
api                    由 proto 生成接口层代码
generate               generate
gen                    generate 缩写
fmt                    fmt 格式化代码
lint                   lint 代码检查
build                  build 编译
all                    重新生产代码并编译
run                    run 本地编译 运行
sonar                  sonar
clean                  clean
help                   show help