我有一个提取一系列tarball的Makefile。现在规则写得像:
dirname:
tar zxvf file.tar.gz
以及依赖于展开的tarball引用dirname
的其他目标。但是,为每个tarball定义这样的规则是一种杂乱无章。所以,我正在尝试使用eval
函数来自动生成这些规则。我的尝试看起来像这样:
TARFILES = $(wildcard *.tar.gz *.tgz)
define extract_tmpl =
$(shell tar tf $(1) | head -1):
tar zxvf $(1)
endef
$(foreach file, $(TARFILES), $(eval $(call extract_tmpl, $(file))))
但它似乎不起作用。我正在测试这个tarball(在同一个目录中):
$ ls Python-2.6.6.tgz
Python-2.6.6.tgz
$ tar tf Python-2.6.6.tgz | head -1
Python-2.6.6/
$ make Python-2.6.6/
make-3.79.1-p7: *** No rule to make target `Python-2.6.6/'. Stop.
它似乎应该对我有用,但老实说,我甚至不确定我怎么能看到它扩展到什么。这里有什么明显的错误吗?
答案 0 :(得分:5)
=
之后您不需要define
。tar zxvf $(1)
default
的规则定义为Makefile中的第一个规则,该规则取决于将要创建的所有目录,因此如果您只运行make
,它将提取所有压缩包。default
定义为PHONY
规则,因为它不会创建任何名为default
的文件。这就是Makefile
的样子(并使用当前目录中的2个tarball进行测试):
TARFILES = $(wildcard *.tar.gz *.tgz)
define extract_tmpl
$(shell tar tf $(1) | head -1):
tar zxvf $(1)
# ^
# HARD-TAB
#
endef
TAR_DIRS := $(foreach file, $(TARFILES), $(shell tar tf $(file) | head -1))
default: $(TAR_DIRS)
$(foreach file, $(TARFILES), $(eval $(call extract_tmpl, $(file))))
.PHONY: default
不使用eval
而只使用static pattern rules
的替代解决方案:
.extract_file.tar.gz
或.extract_file.tgz
作为空文件,如果已经解压缩,则不会重新提取存档这是Makefile
:
TARFILES = $(wildcard *.tar.gz *.tgz)
EXTRACT_TARGETS := $(addprefix .extract_,$(TARFILES))
CLEAN_TARGETS := $(addprefix .clean_,$(TARFILES))
default: $(EXTRACT_TARGETS)
clean: $(CLEAN_TARGETS)
$(CLEAN_TARGETS): .clean_%: .extract_%
rm -rf "$(shell tar tf $(patsubst .extract_%,%,$<) | head -1)"
rm -f $<
$(EXTRACT_TARGETS): .extract_%: %
tar zxf $<
touch $@
.PHONY: default clean $(CLEAN_TARGETS)