makefile学习

下面是一个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 声明了 cleanall 两个“伪目标”,表示它们不存在对应的实际文件。如果没有添加 .PHONY,那么当当前目录下存在一个名为 clean 的文件时,执行 make clean 会出现错误。

.PHONY 还可以用于指定需要执行的任务,如在构建 Docker 镜像时,可以将 docker 添加到 .PHONY 列表中,确保每次执行 make docker 时都能重新构建 Docker 镜像。例如:

.PHONY: docker

docker:
    docker build -t myimage .

在上述示例中,添加了 docker 目标,并指定了需要执行的构建 Docker 镜像的命令,这样每次运行 make docker 时都会重新构建 Docker 镜像。

你可能感兴趣的:(linux,学习,docker,容器)