Hello,

        I tested this a bit I think it's a bug.  However, I'm not
completely familiar with make so I could have overlooked something.  I
looked at the online manual at:

http://www.gnu.ai.mit.edu/manual/make/html_node/make_toc.html
http://www.gnu.ai.mit.edu/manual/make/html_node/make_112.html#SEC111

and did not find this error (although the first incompatbility listed may
have something to do with this bug).  I also read the documentation and I
don't think I should be getting this behavior.

Thanks,
John Paden

I tested this on three systems and got the same results:
Linux jack 2.0.36 #2 Sun Feb 21 15:55:27 EST 1999 i686 (Debian 2.2)
        GNU Make version 3.78.1, i586-pc-linux-gnu
SunOS cleric 5.6 Generic_105181-11 sun4u sparc SUNW,Ultra-60
        GNU Make version 3.75
OSF1 hopper V4.0 878 alpha
        GNU Make version 3.74

Here is a Makefile that demonstrates the bug (the rest of the email):

# 
# This makefile must be named: Makefile
#   (I don't know how to get at the filename of the Makefile
#   for recursive calls to the same Makefile)
# You may need to set the CC and AR variables

# I think the mechanism that checks the dates in an
# archive file (.a) may have problems.

# Typing "make" runs the example (makes all the necessary
# files).

# Procedure of this Example:
#       1) Create two files first.c and second.c.
#       a) I think having something in the files
#          may help first.o to close after second.o
#          despite being the first implicit rule to
#          execute.
#       b) You can just touch the files to simulate
#          first.o finishing after second.o:
#             touch second.o; sleep 1; touch first.o
#       2) Run make clean
#       3) Run make
#       4) Run ls -lt first.o second.o
#       5) Run make
#       If first.o is older than second.o, when you run
#       make in step 5 it will re-insert first.o.  I
#       don't it should since first.o hasn't changed in
#       the archive or in the object file.
#       One possibility that could cause problems is the
#       method that the file system uses to assign the
#       last-modified date to a file and the way "ar"
#       assigns that dat in the archive.  If "ar" or the
#       ".o" files don't use the last-modified date of
#       the file after the file is closed could this
#       cause the problem?

#       I noticed that when you have > 2 files, the last file
#       in the archive (according to ar -vt) is never
#       re-inserted.  Also, if the files are compiled with an
#       implicit rule (instead of explicitly with the
#               $(CC) -c $(CPPFLAGS) $(CFLAGS)
#       command as done below), AND the object files are 
#       written in the same order as the are inserted into
#       the archive, everything works.  But when the order
#       in which the object files are written is different
#       from the order in which they are inserted, some of
#       the object files will be re-inserted every time
#       we make the library.  I also noticed that it is
#       consistent.  In other words, a particular order
#       of written files means that a particular set of files 
#       will always be re-inserted into the archive.

#       Using "ar -u" gets around the problem though.  The
#       rules still fire, but "ar" will do nothing because
#       it only inserts the entry if the time stamp is newer.

# User Defined Variables
OBJS = first.o second.o
LIBNAME = libtest.a

# Rules
.SILENT :
.PHONY : clean
.PHONY : demo

default: demo
all: $(LIBNAME)($(OBJS))

$(LIBNAME)($(OBJS)) : $(OBJS)

clean :
        -$(RM) $(OBJS) $(LIBNAME)

demo :
        @echo
        @echo Create the C files needed
        @echo
        touch first.c
        touch second.c

        @echo
        @echo Start from scratch
        @echo
        $(MAKE) clean

        @echo
        @echo Generate the object files
        @echo
        $(MAKE) all

        @echo
        @echo Simulate first.o being created before second.o
        @echo
        @echo $(CC) -c $(CPPFLAGS) $(CFLAGS) first.c
        $(CC) -c $(CPPFLAGS) $(CFLAGS) first.c
        @echo sleep 2
        sleep 2
        @echo $(CC) -c $(CPPFLAGS) $(CFLAGS) second.c
        $(CC) -c $(CPPFLAGS) $(CFLAGS) second.c

        @echo
        @echo Generate the library file
        @echo
        $(MAKE) all

        @echo
        @echo "Note that first.o was created first (it's older)"
        @echo
        @echo ls -lt first.o second.o
        ls -lt first.o second.o

        @echo
        @echo The following make should do nothing,
        @echo but it re-inserts first.o into libtest.a
        @echo
        $(MAKE) all

        @echo
        @echo Simulate second.o being created before first.o
        @echo
        @echo $(CC) -c $(CPPFLAGS) $(CFLAGS) second.c
        $(CC) -c $(CPPFLAGS) $(CFLAGS) second.c
        @echo sleep 2
        sleep 2
        @echo $(CC) -c $(CPPFLAGS) $(CFLAGS) first.c
        $(CC) -c $(CPPFLAGS) $(CFLAGS) first.c

        @echo
        @echo Generate the library file
        @echo
        $(MAKE) all

        @echo
        @echo "Note that second.o was created first (it's older)"
        @echo
        @echo ls -lt first.o second.o
        ls -lt first.o second.o

        @echo
        @echo The following make should do nothing,
        @echo but it re-inserts second.o into libtest.a
        @echo
        $(MAKE) all

        @echo
        @echo Clean up
        @echo
        $(MAKE) clean
        -$(RM) first.c second.c


Reply via email to