3
votes

Can someone shed light on the difference here:

$(tsdir)/proj has prerequisites $(tsdir)/proja and $(tsdir)/projb. I want proja's and projb's makefile to be called every time I have to build proj. If proja or projb are out of date and are updated, then their makefile will touch $(tsdir)/proja and $(tsdir)/projb respectively. If those files are then newer than $(tsdir)/proj, then rebuild proj.

I have this working by using the below code and the FORCE target. If I try and switch to use .PHONY targets, this doesn't work. I prefer .PHONY as that is supposedly the more 'correct' way of doing this. But it doesen't work and I don't know why. proja's and projb's makefiles aren't called with .PHONY targets, but proj is rebuilt.

I am using GNU make 3.81.

Thanks Nachum

$(tsdir)/proj: $(tsdir)/proja $(tsdir)/projb
...

$(tsdir)/%: FORCE  
    make -C $(prereqdir)/$*

FORCE:

#or

$(tsdir)/proj: $(tsdir)/proja $(tsdir)/projb
...

.PHONY: $(addprefix $(tsdir)/, $(projects))

$(tsdir)/%:  
    make -C $(prereqdir)/$*
2
Shouldn't that proj at the end of be in I want proja's and projb's makefile to be called everytime I have to build proja? - bobbogo

2 Answers

4
votes

.PHONY targets are supposed to represent tasks, not real files, where implicit rule search works only for files. Thus, there is no way to build a phony target with an implicit rule.

From Phony Targets chapter:

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

In your case I would just use explicit rule, may be with a static pattern:

.PHONY: $(addprefix $(tsdir)/, $(projects))

$(addprefix $(tsdir)/, $(projects)) : $(tsdir)/% :  
    make -C $(prereqdir)/$*
1
votes

I suspect you can get the result you want by adding a phony dependency to the (real) time-stamp files, one removed from the master project proj.

.PHONY: phony
phony: ; : $@

ts := $(addprefix $(tsdir)/, $(projects))

${ts} : $(tsdir)/%: phony
    make -C $(prereqdir)/$*

$(tsdir)/proj: $(tsdir)/proja $(tsdir)/projb
...