多依赖makefile目标

时间:2018-06-21 20:33:56

标签: makefile dockerfile

我遇到的问题是一个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),以防万一:

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

... super secret sauce

更新(答案)

感谢@G.M.,最后得到:

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-$*文件模式)并行运行
  • 比以前更加美丽

2 个答案:

答案 0 :(得分:2)

如果长期绘制依赖关系图,您会发现从allpullbuild都有多条路径-一条通过{{1 }}和node。但是jdk8已通过一条路径到达/更新了makepull时,将假定它们都是最新的,因此,不考虑进一步更新它们-无论进行任何更改定位特定变量。

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

build

注意:您当前拥有使用相同输入/输出文件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 的所有build食谱。如果您想使用并行构建(例如DockerFile等),则会引起问题。如果可能的话,最好使用模式规则匹配的词干来唯一地标识输出文件。

答案 1 :(得分:1)

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

make all

,并且如果pullbuildnodejdk8都不是现有文件,make应该构建pullbuild。如果看到仅生成pull,则可能是因为调用了make而未指定目标。在这种情况下,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