Libraries

Good programming practice includes saving compiled object code in an object library, a collection of object modules stored in a single file. When a library is linked with your code, only the object modules referred to in the library are actually linked into the final program.

If object code is stored in a library, your makefile must have access to the code from that library. This means you have to tell make when a target is a library, since make requires special handling to check whether library members are up to date.

To make a library, specify the library as a target with the .LIBRARY attribute, and give as prerequisites the object files that you want to make members. If you specify the prerequisites in the form:
name (member)
then make automatically sets the .LIBRARY attribute for the target, and interprets the member inside the parentheses as a prerequisite of the library target.
make employs the .LIBRARY attribute to determine whether a particular target is a library:
LIBOBJS = mod1 mod2 mod3
userlib$(LIBSUFFIX) .LIBRARY : $(LIBOBJS:+"$O")
This example tells make that userlib$(LIBSUFFIX) has the .LIBRARY attribute and is therefore a library. The prerequisites for this target are the object files
mod1$O mod2$O mod3$O
This example makes use of the LIBSUFFIX macro that is defined in the startup file.LIBSUFFIX specifies the usual suffix for libraries, just as O specifies the usual suffix for object files. (For brevity, the default rules also define the A macroequal in value to LIBSUFFIX.)

make gives the prerequisites of a .LIBRARY target the .LIBRARYM attribute. The library name is also internally associated with the prerequisites. This lets the file binding mechanism look for the member in an appropriate library if an object file cannot be found.

Using these features, you can write:
mylib$A : mylib$A(mem1$O) mylib$A(mem2$O)
    recipe for making library
Note that make gives the A macro the same value as the LIBSUFFIX macro in the startup file.
In any rule, you can use a construct of the form:
libname$(LIBSUFFIX)(member)
to refer to an object file contained in a library. This kind of construct can appear as a target or prerequisite. For example, you might have:
 prog$E : prog$O mylib$(LIBSUFFIX)(module$O)
     # recipe for linking object and library
make infers the following information from this:
  • The file mylib$(LIBSUFFIX) is a library.
  • Therefore, the module is a member of that library; and ,module$O it is a prerequisite for the library.
  • The module$O module inside the library is a prerequisite of prog$E (that is, the program links in that module).

The recipe in this rule should tell make how to link the object file with the library module. The library metarules in the standard startup file specify themeans for updating libraries.

If a target or prerequisite has the form:
name ((entry))
make gives the entry the .SYMBOL attribute, and gives the target name the .LIBRARY attribute. make then searches the library for the entry point, and returns not only the modification time of the member which defines the entry, but also the name of the member file. This name then replaces entry, and make uses it for making the member file. Once bound to a library member, make removes the .SYMBOL attribute from the target.