The Make File

To ease compilation of Windows programs, you can use the NMAKE utility included in the Microsoft C Professional Development System. Whenever you change something in one of the HELLOWIN source files, all you need do is run:

NMAKE HELLOWIN.MAK

to create the updated HELLOWIN.EXE executable.

A make file consists of one or more sections, each of which begins with a left-justified line that lists a target file, followed by a colon, followed by one or more dependent files. This line is followed by one or more indented command lines. These commands create the target file from the dependent files. If the last modification date and time of any of the dependent files is later than the last modification date and time of the target file, then NMAKE executes the indented command lines.

Normally, NMAKE will update only the target file in the first section of the make file. However, if one of the dependent files is itself a target file in another section of the make file, then NMAKE will update that target first.

The HELLOWIN.MAK make file contains two sections. The first runs the LINK.EXE linker if HELLOWIN.OBJ or HELLOWIN.DEF has been altered more recently than HELLOWIN.EXE:

hellowin.exe : hellowin.obj hellowin.def

link hellowin, /align:16, NUL, /nod slibcew libw, hellowin

rc hellowin.exe

The second section runs the CL.EXE C compiler if HELLOWIN.C has been changed more recently than HELLOWIN.OBJ:

hellowin.obj : hellowin.c

cl -c -Gsw -Ow -W2 -Zp hellowin.c

Because HELLOWIN.OBJ is a dependent file in the first section of the make file and a target file in the second section, NMAKE will check whether HELLOWIN.OBJ needs updating before re-creating HELLOWIN.EXE. Thus, the make file should be analyzed from the bottom up.

Running the CL.EXE C compiler creates the HELLOWIN.OBJ object module from the HELLOWIN.C source code file:

cl -c -Gsw -Ow -W2 -Zp hellowin.c

Several compiler switches are required (or recommended) for compiling Windows programs:

The -c switch indicates that the program should be compiled only and not yet linked. The link is a separate step.

The -Gsw switch is actually two switches: -Gs and -Gw. The -Gs switch disables checks for stack overflow. Because stack overflow messages are written to standard error output (and are hence ignored by Windows), it's best simply to be sure that you are using a sufficient stack. (Four kilobytes is recommended.)

The -Gw switch is a special Windows switch that inserts special prolog and epilog code in all far functions in the program. This code (which I'll discuss in Chapter 7) aids Windows in moving code and data segments in memory.

The -Ow switch concerns optimization. With this switch the compiler will avoid some optimizations that may cause problems specifically with Windows programs.

The -W2 switch enables warning level 2 for displaying warning messages. You should make an effort to write programs that show no warning messages when you compile with this switch. Windows will not tolerate sloppy programming, which can lead to nasty bugs.

The -Zp switch packs structure fields on byte boundaries. This is required for some of the structures defined in WINDOWS.H that programs use to communicate with Windows. Windows assumes that all structures are packed.

The first section of the make file runs two commands if HELLOWIN.OBJ or HELLOWIN.DEF has been altered more recently than HELLOWIN.EXE. The first indented command runs LINK:

link hellowin, /align:16, NUL, /nod slibcew libw, hellowin

The first field indicates the HELLOWIN.OBJ object file. The .OBJ extension is assumed. The second field would normally list the name of the executable file, but I'm letting it default to HELLOWIN.EXE. The /align:16 switch tells LINK to align code and data segments on 16-byte boundaries in the HELLOWIN.EXE file for better space efficiency. (The default is 512-byte boundaries.)

The third field is the name of an optional map file. This is set to NUL to create no map file. The fourth field lists the libraries followed by the /nod (no default libraries) switch. SLIBCEW.LIB is the small model Windows C run time library created during installation of the Windows Software Development Kit.

LIBW.LIB is an import library that contains information LINK uses to set up a table in the .EXE file so that Windows can dynamically link the program's calls to Windows functions with the Windows dynamic link libraries that contain those functions.

The fifth field indicates the name of the program's module definition file, HELLOWIN.DEF. The .DEF extension is assumed. (I'll discuss this file later in this chapter.) It contains information that LINK uses to construct HELLOWIN.EXE.

The second indented command runs the Windows resource compiler, RC.EXE:

rc hellowin.exe

The resource compiler sets a couple flags in the HELLOWIN.EXE file to indicate that this is a Windows 3–compatible application. Primarily, this avoids a Windows 3 message that warns the user that the program may crash because it has not been modified for protected-mode operation. Later on, we'll use the resource compiler to add menus and dialog boxes to our Windows programs.