此Makefile有什么问题?需要运行两次才能工作

时间:2019-06-06 12:06:38

标签: docker makefile

运行make一次会产生一个错误,表明$(shell docker run -d $(IMAGE))不能按预期工作。

但是,第二次跑步就像是魅力。

似乎像make build-image build-api导致目标build-api不等待构建映像完成?我应该引入延迟执行吗? (臭名昭著的睡眠:D)

$ cat Makefile
.PHONY: build

IMAGE := tensorflow-serving-grpc

build: build-image build-api

clean:
        -docker rmi -f $(IMAGE)

build-image:
        docker build -t $(IMAGE) .

build-api: CONTAINER_ID:=$(shell docker run -d $(IMAGE))
build-api:
        docker wait $(CONTAINER_ID)
        docker cp $(CONTAINER_ID):/usr/src/vendor ./
        docker rm -f $(CONTAINER_ID)

2 个答案:

答案 0 :(得分:2)

如果不等待,那是因为您允许使用var map = new Dictionary<Tuple<string, string>, int>(); map.Add(new Tuple<string, string>(key1, key2), 54); map.Add(new Tuple<string, string>(key1, key2), 47); if (map["1"] != null) {} // => this gives an error 选项进行并行执行从$(shell ...)运行它。除非您知道自己要做什么,否则应避免使用$(shell ...)。

您还应该通过声明先决条件来防止并行执行-jNbuild-image

build-api

答案 1 :(得分:2)

您有一个具有目标作用的特定于目标的变量,并且您做出了错误的假设,即在运行规则之前不会扩展该变量。我将切换为使用bash变量,并串联要在单个shell中运行的配方,如下所示:

build-api: build-image
    CONTAINER_ID=$$(docker run -d $(IMAGE)); \
    docker wait $${CONTAINER_ID}; \
    docker cp $${CONTAINER_ID}:/usr/src/vendor ./; \
    docker rm -f $${CONTAINER_ID};

另一种选择是创建一个目标,该目标创建容器ID,并将其存储在文件中。使build-api依赖于此新目标,然后在build-api中,让每个配方行从文件中读取值。