生成文件 foreach
Makefile foreach
我正在尝试创建一个 makefile,它将一些先决条件文件下载到某个路径。
但遗憾的是 foreach documentation 缺少详细信息和示例。
我想要这样的东西:
image_files = a b
image_versions = 701.2 802.1
image_path = images
images = $(foreach ...) ??
我希望扩展到:
images/701.2/a
images/701.2/b
images/802.1/a
images/802.1/b
并且有一个虚假目标可以从 URL 下载它们,例如:
mytarget: $(images)
wget somepath $<
我该怎么做?
好的,我已经更进一步了。但我仍然对如何让它发挥作用感到困惑。
tag = my-registry:8443/boot-server-data
versions = 557.0.0 607.0.0
images_a = $(foreach ver, $(versions), images/$(ver)/coreos_production_pxe_image.cpio.gz)
images_b = $(foreach ver, $(versions), images/$(ver)/coreos_production_pxe.vmlinuz)
all: build
.PHONY: build $(images_a) $(images_b)
build:
./make-profiles
docker build -t $(tag) .
docker push $(tag)
$(images_a):
wget http://stable.release.core-os.net/amd64-usr/$(foreach version... but depends on each image)/coreos_production
你是怎么做到的?
事实上,我只希望它下载不存在的图像。但出于某种原因,它每次都会下载它。我使用 Make 已经有好几年了。我通常使用另一个构建工具,但需要修改该构建工具以使其执行我在这里想要的操作。所以我想我会同时鞭打它。事实证明比预期的要难一些。
你很接近,但问题不在于foreach
。让我们看一下执行下载的部分。当 make 读取 makefile 时,它以类似的方式结束(为了清楚起见,稍微缩短了名称):
images/1/file.cpio.gz images/2/file.cpio.gz:
<recipe>
如果,由于某种原因,make 决定重建 images/1/file.cpio.gz
说,此时它将扩展配方,并将该扩展的每一行传递给分开 shell.
你的工作是编写一个不关心目标是 images/1/file.cpio.gz
还是 images/2/file.cpio.gz
的食谱。这是另一种说法,说明配方应该使用像 $@
这样的宏(它将扩展到目标)。
草图:
${images_a}:
wget -O $@ http://stable.release.core-os.net/amd64-usr/$@
您可能需要修改 $@
以便 wget 获得正确的 url。举个例子:
${images_a}:
wget -O $@ http://stable.release.core-os.net/$(dirname $@)/deeper/$(notdir $@)
关于您的原始 makefile 的一个抱怨:依赖关系是错误的。 build
需要下载完成才能运行。
.PHONY: build
build: $(images_a) $(images_b)
...
这些图像也不是假的(只要确保你不会在文件名附近 make 撒谎)。
以这种方式编写 makefile 的巨大优势在于它是并行安全的(这就是 make 的 whole 点)。当-j
生效时,两个wgets可以同时进行,下载时间减半
我正在尝试创建一个 makefile,它将一些先决条件文件下载到某个路径。
但遗憾的是 foreach documentation 缺少详细信息和示例。
我想要这样的东西:
image_files = a b
image_versions = 701.2 802.1
image_path = images
images = $(foreach ...) ??
我希望扩展到:
images/701.2/a
images/701.2/b
images/802.1/a
images/802.1/b
并且有一个虚假目标可以从 URL 下载它们,例如:
mytarget: $(images)
wget somepath $<
我该怎么做?
好的,我已经更进一步了。但我仍然对如何让它发挥作用感到困惑。
tag = my-registry:8443/boot-server-data
versions = 557.0.0 607.0.0
images_a = $(foreach ver, $(versions), images/$(ver)/coreos_production_pxe_image.cpio.gz)
images_b = $(foreach ver, $(versions), images/$(ver)/coreos_production_pxe.vmlinuz)
all: build
.PHONY: build $(images_a) $(images_b)
build:
./make-profiles
docker build -t $(tag) .
docker push $(tag)
$(images_a):
wget http://stable.release.core-os.net/amd64-usr/$(foreach version... but depends on each image)/coreos_production
你是怎么做到的?
事实上,我只希望它下载不存在的图像。但出于某种原因,它每次都会下载它。我使用 Make 已经有好几年了。我通常使用另一个构建工具,但需要修改该构建工具以使其执行我在这里想要的操作。所以我想我会同时鞭打它。事实证明比预期的要难一些。
你很接近,但问题不在于foreach
。让我们看一下执行下载的部分。当 make 读取 makefile 时,它以类似的方式结束(为了清楚起见,稍微缩短了名称):
images/1/file.cpio.gz images/2/file.cpio.gz:
<recipe>
如果,由于某种原因,make 决定重建 images/1/file.cpio.gz
说,此时它将扩展配方,并将该扩展的每一行传递给分开 shell.
你的工作是编写一个不关心目标是 images/1/file.cpio.gz
还是 images/2/file.cpio.gz
的食谱。这是另一种说法,说明配方应该使用像 $@
这样的宏(它将扩展到目标)。
草图:
${images_a}:
wget -O $@ http://stable.release.core-os.net/amd64-usr/$@
您可能需要修改 $@
以便 wget 获得正确的 url。举个例子:
${images_a}:
wget -O $@ http://stable.release.core-os.net/$(dirname $@)/deeper/$(notdir $@)
关于您的原始 makefile 的一个抱怨:依赖关系是错误的。 build
需要下载完成才能运行。
.PHONY: build
build: $(images_a) $(images_b)
...
这些图像也不是假的(只要确保你不会在文件名附近 make 撒谎)。
以这种方式编写 makefile 的巨大优势在于它是并行安全的(这就是 make 的 whole 点)。当-j
生效时,两个wgets可以同时进行,下载时间减半