I have noticed nmake.exe
limits its inference-rule search to one missing file. I find no mention of the problem on the Web. Am I missing something?
$ cat Makefile
.SUFFIXES: .a .b .d .e
all: abc.e
.a.b:
copy $** $@
.b.d:
copy $** $@
.d.e:
copy $** $@
$ touch abc.a
$ nmake
NMAKE : fatal error U1073: don't know how to make 'abc.e'
Stop.
$ nmake -n abc.a
'abc.a' is up-to-date
$ nmake -n abc.b
copy abc.a abc.b
$ nmake -n abc.d
NMAKE : fatal error U1073: don't know how to make 'abc.d'
Stop.
This same Makefile produces tbe following with GNU make:
$ make -n
copy abc* abc.b
copy abc* abc.d
copy abc* abc.e
rm abc.b abc.d
Of course, the $**
macro and copy
command aren't as useful in with GNU make. ;-)
Does your version of nmake.exe
handle this any better? Is there a magic switch? Or is it really as broken as it seems?
The problem here is tracking multi-step operations in your build process. Your source files produce intermediate files of some sort which in turn produce the final build output. In a bad universe, you might make changes to a source file and then your final binaries could still be built from stale versions of the intermediate files. Obviously, that would be bad.
GNU make takes the approach of modeling the entire dependency tree at once, and tracing the modified files all the way through to the output. This is great if make is the only build tool you use. This doesn't work well if you have very large projects, so you need to make them in a specific order. This doesn't work well if 'make' doesn't support some tools of your build process, so you would need to run make multiple times anyway.
nmake.exe takes the approach of doing the simplest possible thing: Only doing one pass at a time. It assumes it will be part of a larger tool chain. So if you have multi-pass dependencies, you will need multiple passes of nmake. If your build process requires more than 3 passes, you are probably doing A Bad Thing and you should fix your process. And for crying out loud, if you need multiple passes, just write a script to do it.