我有由版本号(7.0 7.1 7.2)标识的目标
我有一些模板,每个模板都需要替换一个占位符,这样我最终得到每个版本的目录,并且每个目录中的所有文件都有适当的替换。
因此,如果模板目录为:
template\Dockerfile
我想结束:
7.0\Dockerfile
7.1\Dockerfile
7.2\Dockerfile
,其中template\Dockerfile
中的标签已替换为版本号。
这是一个简化的示例。模板文件夹中实际上有4个文件(其中2个在子目录中)。
管道将运行make build-targets
,然后运行适当的docker命令来构建容器并将其推送到存储库-这就是目标。
虽然对所有这些问题都有一个答案是很高兴的,但我想学习,但是我找不到关于如何处理源和目标集的任何信息。
任何建议将不胜感激。
当前版本只有Makefile中的1行:VERSIONS := 7.0 7.1 7.2 latest
要运行的代码将是一系列sed
命令,以获取模板并将文件中的#version#
标记替换为版本号(latest
除外)只会删除标签。
模板源全部位于templates
目录中。作为sed
命令的一部分,生成的文件名将templates
部分替换为版本(包括latest
)。
开始...(不知道这是否好-还在学习)
VERSIONS := 7.0 7.1 7.2 latest
SOURCEDIR := ./templates
DESTDIR := ./
TEMPLATES := $(shell find $(SOURCEDIR) -type f)
# For each file in $(TEMPLATES) for each version in $(VERSIONS), create a corresponding file in $(DEST_DIR)/$(VERSION)
# Replace `#version#` with $(VERSION) in each file, except for the `latest` target where the `#version#` removed.
基于下面提供的解决方案,我的最终代码是:
VERSIONS := 7.0 7.1 7.2 latest
SOURCE_DIR := ./templates
TEMPLATES := $(shell find $(SOURCE_DIR) -type f)
TEMPLATES := $(patsubst $(SOURCE_DIR)/%,%,$(TEMPLATES))
DEST_DIR := ./
.DEFAULT_GOAL := all
.PHONY: all
# $(1): version
# $(2): template file (without the $(SOURCE_DIR)/ stem)
define generate_target_file
$(DEST_DIR)/$(1)/$(2): $(SOURCE_DIR)/$(2)
@echo "Making $$@"
@mkdir -p $$(dir $$@)
@if [ "$(1)" == "latest" ]; then \
sed 's/#version#//g' $$< > $$@; \
else \
sed 's/#version#/$(1)-/g' $$< > $$@; \
fi
all: $(DEST_DIR)/$(1)/$(2)
endef
$(foreach version,$(VERSIONS),$(foreach template,$(TEMPLATES),$(eval $(call generate_target_file,$(version),$(template)))))
list:
@echo 'The following targets are available :'
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | \
awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | \
sort | \
egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | \
xargs -0
答案 0 :(得分:0)
如果使用的是GNU-make,则可以使用make的foreach
函数轻松地创建循环。您可以嵌套它们。 eval
函数可用于以编程方式实例化make构造,而call
函数可让您创建某种宏:
V := 7.0 7.1 7.2 latest
S := ./templates
T := $(shell find $(S) -type f)
T := $(patsubst $(S)/%,%,$(T))
D := ./destdir
.DEFAULT_GOAL := all
.PHONY: all
# $(1): version
# $(2): template file (without the $(S)/ stem)
# $(3): replacement string
define MY_rule
$(D)/$(1)/$(2): $(S)/$(2)
mkdir -p $$(dir $$@)
sed 's/#version#/$(3)/g' $$< > $$@
all: $(D)/$(1)/$(2)
endef
$(foreach v,$(V),\
$(foreach t,$(T),\
$(eval $(call MY_rule,$(v),$(t),$(patsubst latest,,$(v))))))
GNU make manual解释了它是如何工作的。请注意MY_rule
宏的双重扩展,因此必须将某些$
符号加倍。