我有以下项目结构:
+-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文件的先决条件?
或者,一个更直接的问题,实际上可能从错误的角度看待这个问题: 如何引用先决条件中构建的特定目标?
答案 0 :(得分:2)
好的,既然你认为二次扩张是一个障碍,那么再次进行救援$(foreach ...)
和$(eval ...)
(非常强大的组合)。
用以下内容替换你的规则,你应该得到你想要的。
define rule $(SRCDIR)$(1)/$(1).zip: $(SRCDIR)$(1)/$(SRC_FILE) touch $$@ endef $(foreach dir, $(PRJ_DIRS), $(eval $(call rule,$(dir))))