Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile: rule with the same name as subdirectory ignored

This is my makefile:

all: first second

second:
    @echo "==Building second=="

first:
    @echo "==Building first=="

If there is a directory named second, the rule with the same name will be completely ignored by the makefile. If there isn't, everything goes normally.

Note that this happens whether or not the second folder as a Makefile in it.

I ran on this issue while organizing my project: I thought about creating a general Makefile which then invokes the Makefiles in each directories.. so to me it appears natural that the rule has the same name as the folder.

The solution is trivial: change the rule name inside the Makefile...but this behavior seems rather odd: do you have any idea/insight on this, and another possible solution?

I am using GNU Make 3.81, inside Bash 4.2.25, under Ubuntu 12.04.2 LTS.

like image 438
Helios Avatar asked May 01 '13 11:05

Helios


2 Answers

If you're just looking for the reason the rule is not run, it's simple: make tries to build targets. Targets are represented (by default) by the existence of artifacts in the filesystem. It doesn't matter to make whether the artifact is a file or a directory (or, theoretically, anything else).

In order for make to consider a file out-of-date and in need of updating (and thus, for make to run the recipe associated with the target), at least one of two things must be true: either the target (i.e., file or directory) cannot exist or, if it does exist, its last modified time must be older than at least one of its prerequisites.

In your situation you have second, which exists, so the first requirement for rebuilding is not met, and which has no prerequisites, so the second requirement is not met... and so the target is not considered to be out of date and the recipe is not invoked.

As bobbogo suggests, you can tell make that the target should always be rebuilt, regardless of anything else, by declaring the target to be .PHONY. Make will understand that the target does not represent an artifact in the filesystem and is, instead, just a fake target in the makefile used to organize the build.

like image 155
MadScientist Avatar answered Nov 02 '22 12:11

MadScientist


It seems that you want the second rule to always run, whether or not the file (or directory) "second" already exists. You can make second this sort of symbolic target by declaring it as a pre-requisite of .PHONY.

.PHONY: all
all: first second

.PHONY: second
second:
    @echo "==Building second=="
...
like image 24
bobbogo Avatar answered Nov 02 '22 11:11

bobbogo