Что не так с этим Makefile? Необходимо работать дважды, чтобы работать - PullRequest
2 голосов
/ 06 июня 2019

Запуск make один раз приводит к ошибке, свидетельствующей о том, что $(shell docker run -d $(IMAGE)) не работает должным образом.

Однако запуск второго раза работает как чудо.

Похоже, make build-image build-api заставляет целевой build-api не ждать завершения build-image?Должен ли я ввести отложенное исполнение?(печально известный сон: 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 ]

2 голосов
/ 06 июня 2019

У вас есть целевая переменная с побочным эффектом, и вы делаете неверное предположение, что переменная не будет расширена, пока не будет выполнено правило. Я бы переключился на использование переменной bash и объединение рецепта для запуска в одной оболочке следующим образом:

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};

Другим вариантом является создание цели, которая создает идентификатор контейнера и сохраняет его в файле. Сделайте build-api зависимым от этой новой цели, а затем в build-api пусть каждая строка рецепта прочитает значение из файла.

2 голосов
/ 06 июня 2019

Если он не ждет, то это потому, что вы разрешили параллельное выполнение с параметром -jN запустить его из $ (shell ...). Следует избегать использования $ (shell ...), если вы не знаете, что делаете.

Также следует предотвратить параллельное выполнение build-image и build-api, объявив обязательное условие.

.ONESHELL:
build-api: build-image
    set -e
    CONTAINER_ID=`docker run -d $(IMAGE)`
    docker wait $$(CONTAINER_ID)
    docker cp $$(CONTAINER_ID):/usr/src/vendor ./
    docker rm -f $$(CONTAINER_ID)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...