Makefile:在prereq中使用目标文件路径

时间:2011-10-21 22:53:06

标签: makefile gnu-make

我有以下项目结构:

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

每个foo.py文件都是一个具有完全相同名称的不同文件(即它们具有不同的inode,但字面上都称为'foo.py' - 虽然当然实际上名称不是foo.py,只是一个例子。)

我希望创建一个GNU Makefile规则,在运行时会创建以下结构:

+-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 个答案:

答案 0 :(得分:2)

好的,既然你认为二次扩张是一个障碍,那么再次进行救援$(foreach ...)$(eval ...)(非常强大的组合)。

用以下内容替换你的规则,你应该得到你想要的。

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

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