繁体   English   中英

多依赖makefile目标

[英]Multi-dependency makefile target

我遇到的问题是all目标都对设置变量的其他目标具有依赖性,然后运行匹配的依赖性。

结果 -它将运行第一个依赖项,然后停止。

预期 -运行两个依赖项,并在每次运行之间正确设置变量

make足够智能以查看是否已经运行pullbuild并且依赖目标本身没有执行,因此将所有依赖视为完整吗? 还是我只是滥用make而不应该使用它?

说的makefile

repo=rippio
image=default

pull:
    @docker pull $(repo)/$(image):latest

build: pull
    @sed -e 's/{{repo}}/$(repo)/' -e 's/{{image}}/$(image)/' Dockerfile.in > Dockerfile && \
    docker build -t=$(repo)/$(image):custom .
    @rm -f Dockerfile

node: image=node
node: | pull build

jdk8: image=jdk8
jdk8: | pull build

all: | node jdk8

TLDR

它用于:

  1. 拉最新的Docker映像
  2. 针对它运行通用设计的Dockerfile以对其进行自定义
  3. 标记为:custom供内部使用

在不管理许多Dockerfiles情况下以通用方式自定义映像非常方便。

Dockerfile模板( Dockerfile.in ), Dockerfile.in感兴趣:

FROM {{repo}}/{{image}}:latest

... super secret sauce

更新(答案)

感谢@GM ,最终得到:

IMAGE_NAMES := node jdk8
TARGETS     := $(patsubst %,build-%,$(IMAGE_NAMES))

repo=rippio

all: $(TARGETS)

build-%: pull-%
        @$sed -e 's/{{repo}}/$(repo)/' -e 's/{{image}}/$*/' Dockerfile.in > Dockerfile-$* && \
        $docker build -f=Dockerfile-$* -t=$(repo)/$*:custom .
        @rm -f Dockerfile-$*

pull-%:
        @$docker pull $(repo)/$*:latest

这允许:

  • 轻松维护“所有”目标,并且不断增长
  • 通过make -j并行运行(注意Dockerfile-$*文件模式)
  • 比以前漂亮得多

如果您长期绘制依赖关系图,您会发现从all路径到pullbuild都有多个路径-一个通过nodejdk8 make在达到/更新的pullbuild通过一个路径,然后将假定它们都是最新的,因此,不必再费心更新它们-无论任何改变针对特定的变量。

我认为您使用模式规则可以更轻松地实现您想做的事情(假设我理解正确)。

IMAGE_NAMES := node jdk8
TARGETS     := $(patsubst %,build-%,$(IMAGE_NAMES))

repo=rippio

all: $(TARGETS)

build-%: pull-%
        @$sed -e 's/{{repo}}/$(repo)/' -e 's/{{image}}/$*/' Dockerfile.in > Dockerfile && \
        $docker build -t=$(repo)/$*:custom .
        @rm -f Dockerfile

pull-%:
        @$docker pull $(repo)/$*:latest

注意:当前,您具有使用相同输入/输出文件DockerFile所有build配方。 如果您想使用并行构建(如make -j等),那将会引起问题。如果可能的话,使用模式规则匹配的词干来唯一地标识输出文件可能是明智的。

通常,如果您使用以下命令调用make:

make all

并且如果pullbuildnodejdk8是现有文件,则make应该构建pullbuild 如果看到仅产生pull ,则可能是因为您在未指定目标的情况下调用了make。 在这种情况下化妆建立发现Makefile中的第一个目标( pull你的情况)。

无论如何,Makefile中有几个奇怪的方面:您对看起来像虚假目标的对象使用仅订购的先决条件,而这些虚假目标并未这样声明。

我不确定我是否完全了解您要做什么,但是也许这样的事情会是一个很好的起点:

repo=rippio
image=default

.PHONY: all build node jdk8

all: node jdk8

node: image = node
jdk8: image = jdk8

build node jdk8:
    @docker pull $(repo)/$(image):latest && \
    sed -e 's/{{repo}}/$(repo)/' -e 's/{{image}}/$(image)/' Dockerfile.in > Dockerfile && \
    docker build -t=$(repo)/$(image):custom . && \
    rm -f Dockerfile

注意:如果您不用build而是使用默认目标default名称,则可以使用以下方法进一步简化:

repo=rippio

.PHONY: all default node jdk8

all: node jdk8

default node jdk8:
    @docker pull $(repo)/$@:latest && \
    sed -e 's/{{repo}}/$(repo)/' -e 's/{{image}}/$@/' Dockerfile.in > Dockerfile && \
    docker build -t=$(repo)/$@:custom . && \
    rm -f Dockerfile

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM