UNIX® and Sprite allow you to merge files into an archive
      using the ar command.  Further, if the files
      are relocatable object files, you can run
      ranlib on the archive and get
      yourself a library that you can link into any program you want.
      The main problem with archives is they double the space you need
      to store the archived files, since there is one copy in the
      archive and one copy out by itself.  The problem with libraries
      is you usually think of them as -lm rather
      than /usr/lib/libm.a and the linker thinks
      they are out-of-date if you so much as look at them.
PMake solves the problem with archives by allowing you to tell it to examine the files in the archives (so you can remove the individual files without having to regenerate them later). To handle the problem with libraries, PMake adds an additional way of deciding if a library is out-of-date: if the table of contents is older than the library, or is missing, the library is out-of-date.
A library is any target that looks like -lname
      or that ends in a suffix that was marked as a library using the
      .LIBS target.  .a
      is so marked in the system makefile.  Members of an archive are
      specified as archive(member[member...]).
      Thus libdix.a(window.o) specifies the
      file window.o in the archive
      libdix.a.  You may also use
      wildcards to specify the members of the archive.  Just
      remember that most the wildcard characters will only find
      existing files.  A file that is a member of an archive is
      treated specially.  If the file does not exist, but it is
      in the archive, the modification time recorded in the
      archive is used for the file when determining if the file
      is out-of-date.  When figuring out how to make an archived
      member target (not the file itself, but the file in the
      archive – the archive(member) target), special care
      is taken with the transformation rules, as follows:
archive(member) is made to depend on member.
The transformation from the member's suffix to the archive's suffix is applied to the archive(member) target.
The archive(member)'s .TARGET
	  variable is set to the name of the member if member is
	  actually a target, or the path to the member file if
	  member is only a source.
The .ARCHIVE variable for the
	  archive(member) target is set to the name of the
	  archive.
The .MEMBER variable is set to the
	  actual string inside the parentheses.  In most cases,
	  this will be the same as the .TARGET
	  variable.
The archive(member)'s place in the local variables of
	  the targets that depend on it is taken by the value of its
	  .TARGET variable.
Thus, a program library could be created with the following makefile:
.o.a : ... rm -f $(.TARGET:T) OBJS = obj1.o obj2.o obj3.o libprog.a : libprog.a($(OBJS)) ar cru $(.TARGET) $(.OODATE) ranlib $(.TARGET)
This will cause the three object files to be compiled (if
      the corresponding source files were modified after the object
      file or, if that does not exist, the archived object file), the
      out-of-date ones archived in libprog.a, a
      table of contents placed in the archive and the newly-archived
      object files to be removed.
All this is used in the makelib.mk system
      makefile to create a single library with ease.  This makefile looks
      like this:
# # Rules for making libraries. The object files that make up the library # are removed once they are archived. # # To make several libraries in parallel, you should define the variable # "many_libraries". This will serialize the invocations of ranlib. # # To use, do something like this: # # OBJECTS = <files in the library> # # fish.a: fish.a($(OBJECTS)) MAKELIB # # #ifndef _MAKELIB_MK _MAKELIB_MK = #include <po.mk> .po.a .o.a : ... rm -f $(.MEMBER) ARFLAGS ?= crl # # Re-archive the out-of-date members and recreate the library's table of # contents using ranlib. If many_libraries is defined, put the ranlib # off til the end so many libraries can be made at once. # MAKELIB : .USE .PRECIOUS ar $(ARFLAGS) $(.TARGET) $(.OODATE) #ifndef no_ranlib # ifdef many_libraries ... # endif many_libraries ranlib $(.TARGET) #endif no_ranlib #endif _MAKELIB_MK
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/
Questions that are not answered by the
    documentation may be
    sent to <freebsd-questions@FreeBSD.org>.
    Send questions about this document to <freebsd-doc@FreeBSD.org>.