GNU make:生成提取tarball的规则

Fat*_*ror 3 makefile gnu-make

我有一个Makefile,它提取了一系列tarball.现在规则写得像:

dirname:
        tar zxvf file.tar.gz
Run Code Online (Sandbox Code Playgroud)

以及依赖于扩展的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))))
Run Code Online (Sandbox Code Playgroud)

但它似乎没有用.我正在测试这个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.
Run Code Online (Sandbox Code Playgroud)

它似乎应该对我有用,但说实话,我甚至不确定我怎么能看到它扩展到什么.这里有什么明显的错吗?

Tux*_*ude 5

  • =之后不需要了define.
  • 之前应该有一个硬标签 tar zxvf $(1)
  • 可选,定义一个名为defaultMakefile中第一个规则的规则,该规则依赖于将要创建的所有目录,因此如果您只是运行make,它将提取所有tar包.
  • 可选,但良好的做法是定义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
Run Code Online (Sandbox Code Playgroud)

替代解决方案,不使用eval和只是static pattern rules:

  • 如果已经提取,则使用.extract_file.tar.gz.extract_file.tgz作为空文件不重新提取存档
  • 没有评估,但只是静态模式规则,这应该使它与旧版本的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)
Run Code Online (Sandbox Code Playgroud)