3

我有一个提取一系列 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.

似乎它应该对我有用,但老实说,我什至不确定我如何才能看到它扩展到什么。这里有什么明显的错误吗?

4

1 回答 1

6
  • 您不需要=define.
  • 之前应该有一个硬标签tar zxvf $(1)
  • 可选,default在 Makefile 中定义一个称为第一条规则的规则,该规则取决于将要创建的所有目录,因此如果您只运行make,它将提取所有 tarball。
  • 可选,但良好的做法是定义defaultPHONY规则,因为它不会创建任何名为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不使用and just的替代解决方案static pattern rules

  • 使用.extract_file.tar.gz.extract_file.tgz作为空文件,如果已提取档案,则不重新提取档案
  • 没有 eval,只有静态模式规则,这应该使其与旧版本的 make 兼容,如 v3.79
  • 添加了清洁规则

这是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)
于 2013-03-11T21:12:10.007 回答