Makefile 看这一篇就够
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