tags:

views:

222

answers:

2

I have a project that I am working to release that actually contains 3 subprojects, all of which need to be compiled in one go. My makefile looks roughly like this:

all: a b c

a:
    @cd a && make

b:
    @cd b && make

c:
    @cd c && make

Projects A and B both compile fine but for the 3rd project, it tells me there is nothing to be done although switching to the C directory and running make does in fact compile code.

To be a little more specific: Project C in the example above is actually Mozilla's SpiderMonkey. Whereas A and B are code/makefiles that I have written, C is just a raw copy of SpiderMonkey from the Mozilla website. The actually compile command for it is:

make JS_DIST=/usr JS_THREADSAFE=1 JS_HAS_FILE_OBJECT=1

In my master Makefile, I have:

spidermonkey:
    @cd spidermonkey/src && $(MAKE) JS_DIST=/usr JS_THREADSAFE=1 JS_HAS_FILE_OBJECT=1

Running "make spidermonkey" outputs "make: Nothing to be done for `spidermonkey'." How do I get make to run the command?

EDIT: I've tried adding the following lines to my makefile:

.PHONY: spidermonkey

As well as renaming the spidermonkey rule to sm, but still no change.

EDIT: My bad! I had spaces when I should have had a tab. doh!

+1  A: 

Make only checks for the existance of a file (or directory) named the same as the rule target, and if there is (and it is newer than the dependencies) then from make's point of view there is nothing more to do.

So your problem is that you have a spidermonkey rule (with no dependencies) as well as a directory called spidermonkey, and then make thinks "the target is already made, nothing for me to do". To get make to do what you want, rename the spidermonkey rule (or the directory).

Speaking of recursive make by the way, this is not neccessarily a good idea, see Recursive Make Considered Harmful.

hlovdal
+2  A: 

You probably have a file or directory at the toplevel called "spidermonkey". Make thinks this is what its supposed to create, and since it is already there, make stops.

One of the most important rules to follow when writing makefiles is each target should create one file with the same name as the target. In other words, if you have

 a:
       <some command>

That command should produce a single file called "a".

Rules which do not produce files but are only there as placeholders are called phony targets, and they should be declared like this:

 .PHONY: a

Make will then always assume that a has to be remade.

Also, as a general rule do not use "make" to invoke make recursively, use $(MAKE) instead.

EDIT: changed "pseudo" to "phony"

JesperE
I suspect you confused .PSEUDO with .PHONY in your answer! (Change that and you get a +1 from me :-))
Ferdinand Beyer
Just to make clear: Jesper's answer is great except that his "pseudo targets" are in fact called "phony targets" and are declared by ".PHONY:" instead of ".PSEUDO:".
Ferdinand Beyer
Thanks JesperE. I've updated my question. Unfortunately, .PHONY isnt' changing the make behavior. Not sure why.
dave mankoff
Yes, of course. .PHONY is the correct term.
JesperE