Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GNU make: Multiple targets in a single rule [duplicate]

Possible Duplicate:
GNU Makefile rule generating a few targets from a single source file

If I have a Makefile rule like this:

a b c:     echo "Creating a b c"     touch a b c  output: a b c     cat a b c > output 

and I run make -j9 output

make sees the 3 dependencies (a,b,c), looks for how to produce them: (the "a b c" rule above), but what happens next? Should it not realize that the "a b c" rule only needs to be run once to create all 3 targets?

This is what make actually does:

[pavel@orianna test]$ make -j9 output -n echo "Creating a b c" touch a b c echo "Creating a b c" touch a b c echo "Creating a b c" touch a b c                                                                                                                                                                                                                                                                     cat a b c > output                                                                                                                                                                                                                                                              [pavel@orianna test]$ 

The same recipe is run 3 times, once for each dependency to rule "output"!

Does anyone know why it behaves this way?

like image 943
Pavel Avatar asked Aug 16 '11 16:08

Pavel


People also ask

How many targets can a makefile have?

Makefile Syntax The targets are file names, separated by spaces. Typically, there is only one per rule.

Can you have multiple rules in a makefile?

There can only be one recipe to be executed for a file. If more than one rule gives a recipe for the same file, make uses the last one given and prints an error message.

What is $@ in makefile?

The file name of the target of the rule. If the target is an archive member, then ' $@ ' is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), ' $@ ' is the name of whichever target caused the rule's recipe to be run.

What is .phony in makefile?

A phony target is one that is not really the name of a file. It is just a name for some commands to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance.


2 Answers

Your a b c: rule tells Make that this is how to build any of these targets, not how to build all of them. Make is not smart enough to analyze the commands and deduce that running the rule once will build all three. Make knows (from the output rule) that it must rebuild a, b and c, so that's what it does. It runs the first rule once for a, once for b and once for c.

If you want to rebuild them individually, do this:

a b c:     echo "Creating $@"     touch $@ 

If you want to rebuild them all at once, do something like this:

.PHONY: things things:     echo "Creating a b c"     touch a b c  output: things     cat a b c > output 

or better still:

THINGS = a b c .PHONY: things things:     echo "Creating $(THINGS)"     touch $(THINGS)  output: things     cat $(THINGS) > output 
like image 114
Beta Avatar answered Oct 04 '22 17:10

Beta


a b c are three different goals/targets with no prerequisites to it. i,e to say it will build the target whenever it is asked to.

a b c:     echo "Creating a b c"     touch a b c 

You are asking make to build target named output that has a b c as prerequisites. So targets a b c are built sequentially and finally output is built.

Now in your case all the targets gets built invariably when either of one is called. So to avoid redundant build you will have to add prerequisites to targets a,b,c. Build target 'a' only if 'a' does not exist. Similarly for 'b' and 'c'

a b c: $@     echo "Creating a b c"     touch a b c 

However this is not advisable. Ideally Makefile targets should be very specific.

like image 28
Kamath Avatar answered Oct 04 '22 18:10

Kamath