开发者

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 $@
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜