Как сделать несколько целей из набора шаблонов для источника? - PullRequest
0 голосов
/ 11 октября 2018

У меня есть цели, идентифицированные номером версии (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: VERSIONS := 7.0 7.1 7.2 latest

Коддля запуска будет серия команд sed, чтобы взять шаблон и заменить тег #version# в файле номером версии (за исключением latest, в этом случае он просто удалит тег.

Все источники шаблонов находятся в каталоге templates. Как часть команды sed, результирующему имени файла будет заменена часть templates на версию (включая latest).

Aзвездат ... (понятия не имею, хорошо это или нет - все еще учусь)

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

1 Ответ

0 голосов
/ 12 октября 2018

Если вы используете GNU-make, вы можете легко создавать циклы с помощью функции foreach make.И вы можете их вложить.Функцию eval можно использовать для программного создания экземпляров конструкций, а функция 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 объясняет, как это работает,Остерегайтесь двойного расширения макроса MY_rule, поэтому некоторые знаки $ должны быть удвоены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...