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?
Makefile Syntax The targets are file names, separated by spaces. Typically, there is only one per rule.
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.
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.
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With