代码之家  ›  专栏  ›  技术社区  ›  Charly

多依赖makefile目标

  •  0
  • Charly  · 技术社区  · 8 年前

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

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

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

    make 聪明到足以看见 pull build 已经运行并且依赖项目标本身没有执行,因此它认为所有依赖项都已完成?或者我只是在虐待 制作 在某些方面它不应该被使用?

    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. 标记为:自定义供内部使用

    在没有管理很多的情况下,以通用的方式定制图像非常方便。 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 回复  |  直到 8 年前
        1
  •  2
  •   G.M.    8 年前

    如果将依赖关系图绘制出来,您将看到 all 对双方 pull build --一个通过每个 node jdk8 . 但是 make 已达到/更新 建造 然后,通过一条路径将假设它们都是最新的,因此,不必费心进一步更新它们——而不管对目标特定变量的任何更改。

    我认为使用模式规则可能更容易实现您所要做的(假设我理解正确)。

    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 . 如果您想使用并行构建,这将导致问题-- make -j 等等。如果可能的话,最好使用模式规则匹配的词干来唯一地标识输出文件。

        2
  •  1
  •   Renaud Pacalet    8 年前

    通常,如果调用make with:

    make all
    

    如果没有 pull , build , node , jdk8 现有的文件,应该建立 建造 . 如果你只看到 生成时,可能是因为调用make而不指定目标。在本例中,make构建它在makefile中找到的第一个目标( 在你的情况下)。

    不管怎么说,你的Maffic文件中有几个奇怪的方面:你只使用看起来像伪目标的命令的先决条件,这些虚假的目标并没有被声明为这样。

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

    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
    

    注:如果,而不是 建造 指定默认目标 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