Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding makefile dependencies

Tags:

makefile

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 depend 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.

like image 894
hendry Avatar asked May 18 '11 13:05

hendry


People also ask

What are dependencies in a makefile?

A dependency is a file that is used as input to create the target. A target often depends on several files. A command is an action that make carries out. A rule may have more than one command, each on its own line.

What is $@ in makefile?

$@ is the name of the target being generated, and $< the first prerequisite (usually a source file). You can find a list of all these special variables in the GNU Make manual.

Where are makefiles stored?

some projects put their makefile in src/ subdirectory of the root directories of the projects, some projects put their makefiles in the root directory of the project.

How do I clean my makefile?

The Cleanup Rule clean: rm *.o prog3 This is an optional rule. It allows you to type 'make clean' at the command line to get rid of your object and executable files. Sometimes the compiler will link or compile files incorrectly and the only way to get a fresh start is to remove all the object and executable files.


1 Answers

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' ' ') > [email protected]
    @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.

like image 131
Thomas Edleson Avatar answered Oct 07 '22 21:10

Thomas Edleson