我的root in a directory layout中有config.xml
表示的几个小部件。
我在这里的GNUmakefile能够构建它们。虽然如果我更新文件夹,则不会跟踪依赖项。我显然不想依赖一个干净的目标,所以如何跟踪每个文件夹的内容?
WGTS := $(shell find -name 'config.xml' | while read wgtdir; do echo `dirname $$wgtdir`.wgt; done )
all: $(WGTS)
%.wgt:
@cd $* && zip -q -r ../$(shell basename $*).wgt .
@echo Created $@
clean:
rm -f $(WGTS)
我希望像:
%.wgt: $(shell find $* -type f)
会工作,但事实并非如此。 Help
答案 0 :(得分:4)
将Beta's idea与我的结合:
WGTS := $(shell find -name config.xml) WGTS := $(WGTS:/config.xml=.wgt) WGTS_d := $(WGTS:.wgt=.wgt.d) all: $(WGTS) clean: rm -f $(WGTS) $(WGTS_d) -include $(WGTS_d) define WGT_RULE $(1): $(shell find $(1:.wgt=)) $(1:.wgt=)/%: @ endef $(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ)))) %.wgt: @echo Creating $@ @(echo -n "$@: "; find $* -type f | tr '\n' ' ') > $@.d @cd $* && zip -q -r ../$(shell basename $*).wgt .
示例:
$ mkdir -p foo bar/nested $ touch {foo,bar/nested}/config.xml $ make Creating bar/nested.wgt Creating foo.wgt $ make make: Nothing to be done for `all'. $ touch foo/a $ make Creating foo.wgt $ rm foo/a $ make Creating foo.wgt $ make make: Nothing to be done for `all'.
这里唯一的潜在问题是虚拟规则,它允许忽略目标,它不知道如何构建嵌套在目录中的目标。 (在我的例子中为foo / a。)如果那些是需要知道如何构建的真实目标,那么重复的配方定义可能是个问题。
答案 1 :(得分:1)
执行此操作的最佳方法可能是事先明确创建先决条件列表:
define WGT_RULE
$(1).wgt: $(wildcard $(1)/*)
endef
$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ))))
还有另一种非常聪明的方法(这句话让一个优秀的程序员保持警惕)。几年前,我想出了一个左手的kludge来处理目录作为先决条件。如果上述情况不够好,我会看看我是否可以挖掘旧笔记本。
修改:
对不起,我没有考虑子目录。这是一个完整的makefile(我遗漏了clean
规则)应该做的伎俩。
WGTS := $(shell find -name 'config.xml' | while read wgtdir; do echo `dirname $\
$wgtdir`.wgt; done )
all: $(WGTS)
# This constructs a rule without commands ("foo.wgt: foo/bar.txt foo/baz.dat...").
define WGT_RULE
$(1).wgt: $(shell find $(1))
endef
# This invokes the above to create a rule for each widget.
$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ))))
%.wgt:
@cd $* && zip -q -r ../$(shell basename $*).wgt .
@echo Created $@