我遇到的问题是一个all
目标对设置变量的其他对象具有依赖关系,然后运行匹配的依赖关系。
结果-它将运行第一个依赖项,然后停止。
期望-运行两个依赖项,并在每次运行之间正确设置变量
make
足够聪明,可以看到pull
和build
已经运行并且依赖目标本身没有执行,因此它认为所有依赖项都完整吗?还是我只是滥用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
它用于:
非常方便,以通用方式自定义图像,而无需管理许多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-$*
文件模式)并行运行答案 0 :(得分:2)
如果长期绘制依赖关系图,您会发现从all
到pull
和build
都有多条路径-一条通过{{1 }}和node
。但是jdk8
已通过一条路径到达/更新了make
和pull
时,将假定它们都是最新的,因此,不考虑进一步更新它们-无论进行任何更改定位特定变量。
我认为使用模式规则可以更轻松地实现您正在尝试做的事情(假设我理解正确)。
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
,并且如果pull
,build
,node
,jdk8
都不是现有文件,make应该构建pull
和build
。如果看到仅生成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