GNU make: 生成解压tar包的规则

3

我有一个Makefile,它会解压一系列的tarball。目前规则是这样写的:

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.

我认为它应该能够正常工作,但老实说,我甚至不确定如何查看它会扩展成什么。这里有什么明显的问题吗?

1个回答

6
  • define后面不需要加上=
  • tar zxvf $(1)前应该有一个硬制表符。
  • 可选,可以在Makefile中定义一个名为default的规则作为第一个规则,该规则依赖于将要创建的所有目录,这样如果您只运行make,它会提取所有tarball。
  • 可选,但是最好将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,只用静态模式规则的另一种解决方案:

  • 使用.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)

谢谢,这个可行。另外,似乎 make 3.79 没有 eval,这也是我的问题之一。 - FatalError
@FatalError - 如果你需要使用旧版本的make,我已经添加了一种替代方案,只需利用静态模式规则而不是eval。 :) - Tuxdude

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接