I am migrating a Makefile from omake.exe (from ClearCase) to jom.exe/nmake.exe.
A simplified Makefile example:
all: bin1 bin2
rule1 rule2: rule3
@echo creating rule1 and rule2
@touch rule1 rule2
rule3:
@echo creating rule3
@touch rule3
bin1: rule1
@echo creating bin1
@touch bin1
bin2: rule2
@echo creating bin2
@touch bin2
touch simply creates a file or if it already exists it updates the timestamp.
The output with jom/namke is:
creating rule3
creating rule1 and rule2
creating rule1 and rule2
creating bin1
creating bin2
creating rule1 and rule2 is executed twice.
With omake the rule was executed only once with the meaning to create the files rule1 and rule2 in one command (here with touch).
What do I have to change that the command that creates rule1 and rule2 at the same time only is called once?
Thanks Teddy
I don't know anything about either omake or nmake. But I can give you info about standard (POSIX) make and to the extent that those instances of make adhere to the standard, it may be useful.
In standard make, this rule:
rule1 rule2: rule3
@echo creating rule1 and rule2
@touch rule1 rule2
never means "one invocation of the recipe builds both targets". It is interpreted to be exactly the same as if you'd written:
rule1: rule3
@echo creating rule1 and rule2
@touch rule1 rule2
rule2: rule3
@echo creating rule1 and rule2
@touch rule1 rule2
So, in one sense the behavior you see from nmake
could be expected. Except, it never works like that in POSIX make, because POSIX make always runs one rule at a time. So, first it tries to build rule1
and that actually builds both rule1
and rule2
. So then when make investigates whether it needs to build rule2
, it sees it is already up to date and doesn't do anything.
So even though make interprets this rule as two different targets, it has the same effect as only one rule: running the recipe one time updates both targets and make only runs the recipe one time.
If you use GNU make, or some other make, which supports parallel builds, then this behavior no longer works because make might detect that rule2
is out of date before the recipe for rule1
has a chance to update it. But, that's not POSIX.
I can't explain why nmake
doesn't work like this... it's a pretty odd, and limited, implementation of make
.
The traditional way to handle this in POSIX is by introducing a "sentinel file" that collects these multiple targets into one, like this:
rule1 rule2 : sentinel ;
sentinel: rule3
@echo creating rule1 and rule2
@touch rule1 rule2
@touch $@
I have no idea if something like that will work in nmake
.
If you use GNU make, it will work or if you use the current release (4.3) you can explicitly declare grouped targets, like this:
rule1 rule2 &: rule3
@echo creating rule1 and rule2
@touch rule1 rule2