Finding makefile dependencies
I have several widgets denoted by a config.xml
in their root in a directory layout.
The GNUmakefile I have here is able to build them. Though if I update the folders, the dependencies aren't tracked. I don't want to d开发者_运维技巧epend on a clean target obviously, so how do I track the contents of each folder?
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)
I hoped something like:
%.wgt: $(shell find $* -type f)
Would work, but it doesn't. Help.
Combining Beta's idea with mine:
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 .
Example:
$ 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'.
The only potential problem here is the dummy rule that lets make ignore targets it doesn't know how to build which are nested inside the directories. (foo/a in my example.) If those are real targets that make needs to know how to build, the duplicate recipe definition may be a problem.
Probably the best way to do this is to create the prerequisite lists explicitly, beforehand:
define WGT_RULE
$(1).wgt: $(wildcard $(1)/*)
endef
$(foreach targ,$(WGTS),$(eval $(call WGT_RULE,$(targ))))
There is another way that's very clever (a phrase that makes a good programmer wary). Years ago I came up with a left-handed kludge for treating a directory as a prerequisite. I'll see if I can dig up my old notebooks if the above isn't good enough.
EDIT:
Sorry, I didn't consider subdirectories. Here's a complete makefile (I left out the clean
rule) that should do the trick.
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 $@
精彩评论