Implementing Autoconf in NMAKE

11 Mar 2017

One of the big challenges in open source development is the development environment cannot be a rigid standard, but must offer some flexibility to adapt to the environment of whoever wants to compile the source code.

In Linux land, Autoconf became a fairly standard solution to this problem. The person compiling the software runs a "./configure" script which executes a pile of tests against the developer's environment. These can do things like test for compiler options, header files, libraries, or installed programs.

NMAKE's hidden gem is supporting execting a program in the middle of a preprocessor conditional, enabling it to do the same type of thing autoconf does - check for the presence of something and alter behavior dynamically in response.

Take the following short but unfortunately convoluted snippet:

!IF [$(CC) -? 2>&1 | find "/MP" >NUL]==0
CFLAGS=$(CFLAGS) -MP
!ENDIF

This code executes cl.exe -?, pipes errors to NUL, and looks for /MP in the output. /MP is the switch enabling multi processor builds. If find indicates success, the test is satisfied, so if the compiler advertises this support in its help text, the switch is defined so that it will be used; if it's not advertised, then the switch is not used.

This support appears to be present in NMAKE throughout its 32 bit history. Unfortunately, the consequence of putting these checks in makefiles is that they execute every time the makefile is invoked, whereas autoconf scripts are seperate from the compilation phase. However, where relatively few checks are needed, NMAKE still contains sufficient support.

Software on this site uses this technique to implement "just run NMAKE" on source distributions, even though the source itself can be compiled with any version of the compiler released in the last 20 years.