make and archives - dependency problem

Spencer W. Thomas thomas at utah-gr.UUCP
Sat Apr 21 02:44:27 AEST 1984


After fixing make to check dates on the elements of archives properly,
we came up with the following "solution" to making a large library for
which we didn't want to keep all the .o files around.  Warning: this is
horribly convoluted and awful, but it is all generated automatically by
our make-depend script, so we don't worry too hard about that.  You need
(as it turns out) two auxilliary files, which we call 'didwork' and
'donework'.  Below is a makefile fragment, with some explanation of what
is going on.  We also put in a "FASTLIBS" switch to prevent the n**2
behaviour that make exhibits when checking the dates on all elements of
a library (by default, make rereads the library for each element).
FASTLIBS caches the dates incore.  It works fine with the paradigm
below, and is much faster on a large library.

=Spencer

default: updatelib

#
# Files which go into the library.  These are the targets of the make.  Rules
# for generating them are below.
#
OFILES= libI.a(D_trim_tri.o) libI.a(S_trim_tri.o)

#
# newlib - Make the intersection library from scratch
#
newlib: cleanlib updatelib

#
# updatelib - Update the intersection library
#
# explanation: 
# 1. reload the library with any .o files hanging around, so we don't need
#    to recompile them.  Assumption is that they came from a previous make
#    which bombed out because one compilation failed.
# 2. compile all the .o files.  We are fooling make here, by telling it that
#    we are making libI.a(ofile) when we are really making just the ofile.
#    Thus, we touch didwork, to force the updatelib stuff to be run even
#    though the dates on the library elements have not changed (yes, make
#    checks again after the rule is executed!)
# 3. The csh ... line causes the ar to not be done if there are no .o files,
#    avoiding the cost of an unnecessary ranlib.
# 4. Touch the updatelib file to make it up to date, and
# 5. Reset the dates on didwork and donework (really shouldn't be necessary,
#    maybe isn't, just left in as a superstition.)
#
updatelib: libI.a ${OFILES} didwork
	-csh -cf "ar r libI.a *.o && rm *.o && ranlib libI.a"
	touch updatelib
	setdate 'jan 2 1970' didwork donework

#
# Just load .o files hanging around.
#
# This depends on donework instead of didwork.  Both donework and didwork
# always have the same date, but for some reason, once make checks the date
# for a dependency it refuses to believe that you might have changed the date
# behind its back.
libI.a: donework
	-csh -cf "ar r libI.a *.o"
	-rm *.o
	ranlib libI.a
	setdate 'jan 2 1970' didwork donework


#
# cleanlib - delete the library so we can start afresh - make a new empty one
#
cleanlib:
	rm libI.a
	ar rc libI.a


# 
# Make the .o files (automatically generated by make-depend).
# Touch both didwork and donework.  The files are supposed to indicate:
# didwork: some work was done in this invocation of make (some files were
#	   compiled).
# donework: some work was done in the last invocation of make, but the
#	    library has not yet been updated.
#
libI.a(D_trim_tri.o): D_trim_tri.c
	${CC} ${CFLAGS} -c D_trim_tri.c
	touch didwork donework

libI.a(S_trim_tri.o): S_trim_tri.c
	${CC} ${CFLAGS} -c S_trim_tri.c
	touch didwork donework



More information about the Comp.unix mailing list