使用. phony目标作为Makefile中的变量



我有一个Makefile,它包含几个几乎相同的命令,除了参数SCRIPT,它接受与目标相同的值:

.PHONY: create run
create:
docker build -t yoyo --build-arg SCRIPT=create . 
&& docker run -v ${HOME}/.aws/credentials:/root/.aws/credentials:ro yoyo
run:
docker build -t yoyo --build-arg SCRIPT=run . 
&& docker run -v ${HOME}/.aws/credentials:/root/.aws/credentials:ro yoyo

我想做的是将我通过命令行传递的目标转换为一个变量,这样我就可以拥有我的Makefile:

.PHONY: create run
$target:
docker build -t yoyo --build-arg SCRIPT=$target . 
&& docker run -v ${HOME}/.aws/credentials:/root/.aws/credentials:ro yoyo

这可能吗?如果没有,有没有类似的方法来简化我的Makefile?由于

也许更有效的方法是将命令本身封装在函数中。

define yoyo
docker build -t yoyo --build-arg SCRIPT="$1" . && 
docker run - ${HOME}/.aws/credentials:/root/.aws/credentials:ro yoyo
endef
.PHONY: create run
create:
$(call yoyo,create)
run:
$(call yoyo,run)

根据构建配置构建具有相同名称但具有不同功能的Docker映像似乎相当可疑。也许用不同的标签构建会有意义,只是一次?

.PHONY: create run
create run: %: .%-tagged
docker run --rm - ${HOME}/.aws/credentials:/root/.aws/credentials:ro yoyo-$*
.%-tagged: Dockerfile
docker build -t yoyo-$* --build-arg SCRIPT=$* .
touch $@

引起我注意的第一件事是,您正在重建映像,只是为了运行一个不同的脚本。你不需要这样做。您可以在镜像名称后附加一个命令给docker run,它将取代Dockerfile中显示的CMD。我假设删除ARG并相应地更新CMDENTRYPOINT是很简单的。

这意味着您需要一个规则来构建图像:

DOCKER_TAG := latest
DOCKER_IMAGE := yoyo:$(DOCKER_TAG)
# This rule should depend on any generated files that get COPYed in
.docker-build:
docker build -t $(DOCKER_IMAGE) .
touch "$@"

那么你执行图像的规则可以依赖于它。您还可以使用额外的Make变量来减少重复的部分。

AWS_CREDENTIALS_FILE := $(HOME)/.aws/credentials
DOCKER_RUN_OPTS := -v $(AWS_CREDENTIALS_FILE):/root/.aws/credentials:ro
.PHONY: create run
create: .docker-image
docker run $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE) create
run: .docker-image
docker run $(DOCKER_RUN_OPTS) $(DOCKER_IMAGE) run

这将创建一个隐藏文件.docker-image,该文件记录了映像已构建,但是由于有一个规则"build"该文件(通过构建Docker镜像并对其进行touch)可以作为普通的依赖项使用。

TARGETS := $(sort $(MAKECMDGOALS)) # remove duplicates
.PHONY: $(TARGETS)
$(TARGETS):
docker build -t yoyo --build-arg SCRIPT=$@ . 
&& docker run -v ${HOME}/.aws/credentials:/root/.aws/credentials:ro yoyo
然而,我质疑这样一个makefile的有用性。如果你把它写成普通的脚本,你就为你之后的程序员省去了一层复杂性。

最新更新