Makefile: использовать целевой путь к файлу в prereq - PullRequest
1 голос
/ 22 октября 2011

У меня следующая структура проекта:

+-Makefile
+-src/
  +-a/
  | +-foo.py
  +-b/
  | +-foo.py
  +-c/
  | +-foo.py

Каждый foo.py файл - это отдельный файл с абсолютно одинаковым именем (т. Е. У них разные inode, но все они буквально называются 'foo.py'), хотя, конечно, в действительности это имя не foo.py, которое просто пример).

Я хочу создать правило Makefile GNU, которое при запуске создает следующую структуру:

+-Makefile
+-src/
  +-a/
  | +-foo.py
  | +-a.zip
  +-b/
  | +-foo.py
  | +-b.zip
  +-c/
  | +-foo.py
  | +-c.zip

Это самое близкое, что мне удалось выяснить, хотя, конечно, это не удается из-за использования целевой переменной в предварительных требованиях, которая, по-видимому, недопустима:

SRCDIR = src/
PRJ_DIRS = a b c
SRC_FILE = foo.py

# This next rather nasty line turns PRJ_DIRS in to, e.g., src/a/a.zip etc.
ZIP_FILES = $(addprefix $(SRCDIR),$(join $(PRJ_DIRS),$(PRJ_DIRS:%=/%.zip)))'

build: $(ZIP_FILES)

# Next line crashes because we can't use $@ in the prereq
$(ZIP_FILES): $(addprefix $(dir $@), $(SRC_FILE))
        touch $@

Итак, один из способов задать вопрос: Как написать правило, использующее каждый соответствующий файл foo.py в качестве предварительного условия для создания соответствующего файла .zip?

Или, более прямой вопрос, который на самом деле может смотреть на это с неправильной точки зрения: Как я могу сослаться на конкретную цель, которая создается в предварительных требованиях?

1 Ответ

2 голосов
/ 23 октября 2011

Ладно, поскольку вы считаете вторичное расширение клуджем, на помощь снова приходят $(foreach ...) и $(eval ...) (очень мощная комбинация).

Замените ваше правило на следующее, и вы получите то, что хотите.

define rule
$(SRCDIR)$(1)/$(1).zip: $(SRCDIR)$(1)/$(SRC_FILE)
    touch $$@
endef

$(foreach dir, $(PRJ_DIRS), $(eval $(call rule,$(dir))))
...