Maintaining a Library with NMAKE

ID Number: Q71422

1.00 1.01 1.10 1.11 1.12 | 1.01 1.10 1.11 1.12

MS-DOS | OS/2

Summary:

There are several features in NMAKE that make it relatively simple to

maintain libraries by incrementally updating only the modules that

have changed. By using the $? special macro and utilizing the NMAKE

macro substitution capabilities, the whole process can be easily done

with only one call to LIB (the Library Maintenance Utility). The

sample NMAKE description files (makefiles) below illustrate this

procedure.

More Information:

The sample makefiles below keep MYLIB.LIB up-to-date based on the four

object files listed in the OBJS macro. These object files can be based

on C or assembly source files. The list of source-file types can be

extended by adding the appropriate inference rules to the description

file.

The following line is used in sample makefile 1 to maintain the

library:

LIB MYLIB.LIB -+$(?: =-+);

The $? macro expands to the list of all dependents that are out-of-

date with respect to the target file. The "$(?: =-+)" part of the

command-line is a macro substitution to be performed on the $? macro.

This substitution means to expand $? to the list of out-of-date

dependents, but then replace all spaces in the expanded list with the

two-character pair "-+".

For example, assume that only MOD1.OBJ, MOD3.OBJ, and MOD4.OBJ are

each out-of-date with respect to MYLIB.LIB. The $? macro will expand

to the following:

MOD1.OBJ MOD3.OBJ MOD4.OBJ

Therefore, $(?: =-+) will actually cause the macro to be expanded with

substitution as follows:

MOD1.OBJ-+MOD3.OBJ-+MOD4.OBJ

With the rest of the command included, the entire command line to be

executed will appear as follows:

LIB MYLIB.LIB -+MOD1.OBJ-+MOD3.OBJ-+MOD4.OBJ;

Note that the first time a module is added to the library, LIB will

generate a "U4155: module not in library" warning to indicate that the

module you asked to have replaced was not found in the library. This

warning can be ignored because LIB just adds the module in this case,

instead of removing the old module first (since it is not there).

The method above will work correctly as long as there are not too many

modules specified in the OBJS macro. If the macro expansion causes the

command line to exceed the DOS or OS/2 command-line limit (128 or 255

characters, respectively), the LIB invocation will fail. If the number

of modules in the library being maintained makes this a possibility,

then a response file should be generated through the use of the NMAKE

in-line file capability.

Sample makefile 2 below demonstrates the response file method. The

response file created is called MYLIB.LRF and the contents are

generated with the makefile lines between the double angle brackets

(<<). The contents of the makefile are created with macro substitution

that is very similar to that shown above. The major difference is that

for each LIB prompt, matching input lines are needed in the response

file, so newlines must be inserted by the macro substitution. This is

done with the following command:

-+$(?: = &^

-+);

This command says that when expanding the macro for out-of-date

dependents, replace each space with a space, an ampersand (&), a

newline, and then the "-+" character-pair. The caret (^) indicates to

NMAKE that the next character is to be taken literally, so the newline

following it actually gets substituted into the macro. (Because you

actually press ENTER to put in the newline, the end of the macro

substitution must appear on the next line.)

Thus, to follow the first example above, if we assume that only

MOD1.OBJ, MOD3.OBJ, and MOD4.OBJ are out-of-date with respect to

MYLIB.LIB, then the $? macro with this substitution will expand to the

following:

-+MOD1.OBJ &

-+MOD3.OBJ &

-+MOD4.OBJ;

With this method, any number of .OBJ files can be used and will be

correctly handled by LIB.

Note: Because of a bug in NMAKE version 1.11 (shipped with C version

6.00 and 6.00a), the $? macro does not expand correctly unless a

double colon (::) is used in the target-dependency line. If you are

using this version, change the single colon to a double colon for the

dependency involving the library.

For more information on macro substitution or in-line files, see the

documentation or online help for NMAKE supplied with your particular

version of the compiler. For more information on response files, see

the documentation or online help for LIB or LINK.

Sample NMAKE Makefile 1

-----------------------

# The OBJS macro is the list of object files to be kept in library.

OBJS = MOD1.OBJ MOD2.OBJ MOD3.OBJ MOD4.OBJ

.c.obj:

Cl /c $?

.asm.obj:

MASM $?;

mylib.lib : $(OBJS)

LIB MYLIB.LIB -+$(?: =-+);

Sample NMAKE Makefile 2

-----------------------

# The OBJS macro is the list of object files to be kept in library.

OBJS = MOD1.OBJ MOD2.OBJ MOD3.OBJ MOD4.OBJ

.c.obj:

Cl /c $?

.asm.obj:

MASM $?;

mylib.lib : $(OBJS)

LIB $*.LIB @<<MYLIB.LRF

-+$(?: = &^

-+);

<<KEEP

# Note: The word "KEEP" above is optional; it prevents NMAKE from

# deleting the in-line file that is created. This allows you to

# view MYLIB.LRF (after executing NMAKE) if you want to observe

# exactly what gets written to the response file. By default,

# NMAKE deletes all in-line files before terminating.