下面是一个makefile文件例子
pkgs = $(shell go list ./... | grep -v vendor/)
DOCKER_IMAGE_NAME ?= feiyu563/prometheus-alert
BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
BUILDDATE ?= $(shell date -I'seconds')
BUILDUSER ?= $(shell whoami)@$(shell hostname)
REVISION ?= $(shell git rev-parse HEAD)
TAG_VERSION ?= $(shell git describe --tags --abbrev=0)
VERSION_LDFLAGS := \
-X main.Version=$(TAG_VERSION) \
-X main.Revision=$(REVISION) \
-X main.BuildUser=$(BUILDUSER) \
-X main.BuildDate=$(BUILDDATE)
all: format vet test build
.PHONY: format
format:
@echo ">> formatting code"
go fmt $(pkgs)
.PHONY: vet
vet:
@echo ">> vetting code"
go vet $(pkgs)
.PHONY: test
test:
@echo ">> running short tests"
go test -short $(pkgs)
.PHONY: build
build:
@echo ">> building code"
go mod tidy
go mod vendor
GO11MODULE=on GO111MODULE=on GOPROXY=https://goproxy.io \
go build -ldflags "$(VERSION_LDFLAGS)" -o PrometheusAlert
.PHONY: docker
docker:
@echo ">> building docker image"
docker build -t "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)" .
docker tag "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)" "$(DOCKER_IMAGE_NAME):latest"
.PHONY: docker-push
docker-push:
@echo ">> pushing docker image"
docker push "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)"
docker push "$(DOCKER_IMAGE_NAME):latest"
.PHONY: docker-test
docker-test:
@echo ">> testing docker image and PrometheusAlert's health"
cmd/test_image.sh "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)" 8080
其中
BUILDUSER ?=
(
s
h
e
l
l
w
h
o
a
m
i
)
@
(shell whoami)@
(shellwhoami)@(shell hostname)
这是一个 Makefile 文件中的语句。该语句定义了一个变量 BUILDUSER
,用于存储当前用户和主机名信息。具体含义如下:
?=
表示如果该变量未定义,则将其赋值为后面的表达式。$(shell command)
是 Makefile 中的执行外部命令的语法。whoami
命令用于获取当前用户名,hostname
命令用于获取当前主机名。- 因此,
$(shell whoami)@$(shell hostname)
返回形如username@hostname
的字符串,表示当前构建环境的用户和主机名信息。 - 最终,
BUILDUSER
变量被赋值为$(shell whoami)@$(shell hostname)
,即当前构建环境的用户和主机名信息。
在 Makefile 中,变量的定义一般使用 VARNAME = value
或者 VARNAME := value
的方式进行。其中 :=
表示立即展开变量,而 =
则表示延迟展开变量。使用 ?= value
则表示如果变量未定义,则使用默认值进行赋值。
在 Makefile 中,.PHONY
是一个特殊的目标,用于声明一些“伪目标”,这些“伪目标”通常不对应任何实际的文件,仅用于执行一些特定的命令或动作。使用 .PHONY
可以避免由于文件名与目标名相同而导致错误的情况发生。
在 Makefile 中,如果某个目标是“伪目标”,那么应该将其添加到 .PHONY
列表中,例如:
.PHONY: clean all
clean:
rm -rf *.o
all: program
echo "build finished"
program:
gcc -c main.c
gcc -o program main.o
在上面的示例中,.PHONY
声明了 clean
和 all
两个“伪目标”,表示它们不存在对应的实际文件。如果没有添加 .PHONY
,那么当当前目录下存在一个名为 clean
的文件时,执行 make clean
会出现错误。
.PHONY
还可以用于指定需要执行的任务,如在构建 Docker 镜像时,可以将 docker
添加到 .PHONY
列表中,确保每次执行 make docker
时都能重新构建 Docker 镜像。例如:
.PHONY: docker
docker:
docker build -t myimage .
在上述示例中,添加了 docker
目标,并指定了需要执行的构建 Docker 镜像的命令,这样每次运行 make docker
时都会重新构建 Docker 镜像。