本文介绍了Makefile-使用多个目标构建多个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个Docker文件的项目,每个文件都位于我用作Docker镜像标签的命名目录中。我需要为每个Dockerfile构建、测试和推送一个docker映像。我需要做什么才能使用GNU Make进行如下工作?

# BUILDS needs to be a list of directories, not a list of Dockerfiles
BUILDS  := $(wildcard */Dockerfile)
VERSION := $(shell git rev-parse --short=12 --verify HEAD)
DOCKER_REPO_URL := quay.io/reponame

define docker_build =
$(1):
    @echo "Building $$@"
    docker build -t $$@ --force-rm $$@
endef

define docker_test =
$(1):
    @echo "Testing $$@"
    docker inspect $$@
    docker run --rm $$@ help
endef

define docker_push =
$(1):
    @echo "Pushing $$@"
    docker tag $$@ $(DOCKER_REPO_URL):$$@-$(VERSION)
    docker push $(DOCKER_REPO_URL):$$@-$(VERSION)
    docker tag $$@ $(DOCKER_REPO_URL):$$@
    docker push $(DOCKER_REPO_URL):$$@
endef

.PHONY: all build test release clean

all: build test release

build: $(BUILDS)
$(foreach build,$(BUILDS),$(eval $(call docker_build,$(build))))

test: $(BUILDS)
$(foreach test,$(BUILDS),$(eval $(call docker_test,$(test))))

release:
$(foreach image,$(BUILDS),$(eval $(call docker_push,$(image))))

推荐答案

我不确定这是您想要的,但是...

首先考虑BUILD变量。如果我们有三个Docker文件:

foo/Dockerfile
bar/Dockerfile
baz/Dockerfile

然后我们希望BUILDS包含foo bar baz

以下是几次尝试:

BUILDS := $(wildcard */Dockerfile) # this is foo/Dockerfile bar/Dockerfile baz/Dockerfile

BUILDS := $(dir $(wildcard */Dockerfile)) # this is foo/ bar/ baz/

BUILDS  := $(patsubst %/,%, $(dir $(wildcard */Dockerfile))) # this is foo bar baz

粗暴但有效。

现在是规则。通常,规则的目标是该规则构建的文件的名称。在这种情况下,我们必须打破这个惯例,因为我们不知道图像文件的名称。因此,如果目录是foo/,我们可能会有一个名为build_foo的规则:

build_foo:
    @echo "Building foo"
    @echo docker build -t foo --force-rm foo

因为我们不想为每个可能的目录编写规则,所以我们将使用自动变量并创建一个pattern rule

build_%:
    @echo "Building $$@"
    @echo docker build -t $* --force-rm $*

现在"make Build_Foowill work correctly. And we could write a构建所有它们的构建`规则:

build: $(addprefix build_,$(BUILDS))

但这不完全是正确的方法。我们希望按此顺序构建、测试、然后推送每个映像。所以我们想要这样的东西:

push_foo: test_foo

test_foo: build_foo

我们可以使用模式规则执行此操作:

test_%: build_%
    ...

push_%: test_%
    ...

release: $(addprefix push_,$(BUILDS))

现在,"Make Release"将执行所有操作。(如果您将release:作为生成文件中的第一个规则,它将是默认规则,"make"就足够了。)

这篇关于Makefile-使用多个目标构建多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 02:59