tags:

views:

48

answers:

2

I have the following recursive makefile:

.PHONY: all clean

%.subdir:
    $(MAKE) -C src $*
    $(MAKE) -C dict $*

all: all.subdir

clean: clean.subdir

and it works fine:

$ make all
make -C src all
make[1]: Entering directory `/or-1.3.6-fix/src'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/or-1.3.6-fix/src'
make -C dict all
make[1]: Entering directory `/or-1.3.6-fix/dict'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/or-1.3.6-fix/dict'

But it would be more logical to define %.subdir rules as phony:

.PHONY: all clean all.subdir clean.subdir

and now make stops working as I want:

$ make all
make: Nothing to be done for `all'.
$ make -d all
...
Updating goal targets....
Considering target file `all'.
 File `all' does not exist.
  Considering target file `all.subdir'.
   File `all.subdir' does not exist.
   Finished prerequisites of target file `all.subdir'.
  Must remake target `all.subdir'.
  Successfully remade target file `all.subdir'.
 Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
make: Nothing to be done for `all'.

Can somebody explain me why (or even better point me to make documentation)?

+1  A: 

If you are using GNU make, see the official Make manual

Make isn't doing anything because it doesn't see any files to make (since they are all phony). Ensure that your default implicit target isn't phony so that make has something to build.

Update: From this section of the make manual:

Since it knows that phony targets do not name actual files that could be remade from other files, make skips the implicit rule search for phony targets.

Therefore, your implicit targets are never searched for because they are phony.

You can achieve what you are trying to do another way. Try this:

SUBDIRS := all clean
.PHONY: $(SUBDIRS)

$(SUBDIRS):
    echo $(MAKE) -C src $@
    echo $(MAKE) -C dict $@
bta
@bta: Thank you for the answer. I have read the docu, so if you point me the exact quote from the docu, I can rate your answer. More over your suggestion about non-phony default target is wrong.
dma_k
Answer has been updated with a specific section about phony rules and implicit targets, as well as an alternate way to approach the problem.
bta
@bta: Thanks, now looks much better.
dma_k
+1  A: 

You're right, it would make more sense to define the subdir rules as PHONY. But Make does not consider implicit rules for PHONY targets, so you'll have to rewrite that rule. I suggest the following:

SUBDIR_TARGETS = all.subdir clean.subdir
.PHONY: all clean $(SUBDIR_TARGETS) 

$(SUBDIR_TARGETS): %.subdir:
    $(MAKE) -C src $*
    $(MAKE) -C dict $*

all: all.subdir
clean: clean.subdir
Beta
@Beta: Thanks for the nice hint! Very good. I would rather prettify a bit more and say `PHONY_TARGETS := all clean` and then `.PHONY: $(PHONY_TARGETS) $(addsuffix .subdir,$(PHONY_TARGETS))`
dma_k