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