Search code examples
makefilearchiveprerequisites

make updates static lib archive even if newer than pre-requisites


I am building a static library from source files foo.c, bar.c and baz.c Even though the library is timestamped newer than foo.o, bar.o and baz.o it still gets rebuilt every time I run make. here is the Makefile

CC      = gcc $(CCFLAGS)
CCFLAGS = -std=gnu17 -mtune=corei7 -flto -fopenmp -pthread -Wall -pedantic -O3 -I../include
#LDFLAGS = -L../lib -lm -ldds -ldealerV2
LDFLAGS = --verbose

SRCS = foo.c bar.c baz.c
OBJS = $(patsubst %.c,%.o,$(SRCS) )
LIBRARY = libfoo.a

library : $(OBJS)
    ar -rcs $(LIBRARY) $?
    ar -t $(LIBRARY)
    touch -c $(LIBRARY)

%.o : %.c
    $(CC) -c -o $@ $<

clean :
        rm -f *.o a.out

now setup the initial conditions

$ make clean
rm -f *.o a.out
$ touch *.c
$ ls -l
total 48
-rw-rw-r-- 1 greg21 greg21  3742 Dec  9 14:02 bar.c
-rw-rw-r-- 1 greg21 greg21  3916 Dec  9 14:02 baz.c
-rw-rw-r-- 1 greg21 greg21  3220 Dec  9 14:02 foo.c
-rw-rw-r-- 1 greg21 greg21 29668 Dec  9 14:02 libfoo.a
-rw-rw-r-- 1 greg21 greg21   618 Dec  9 13:58 Makefile

Now do the first make -- updates libfoo.a as it should

$ make
gcc -std=gnu17 -mtune=corei7 -flto -fopenmp -pthread -Wall -pedantic -O3 -I../include -c -o foo.o foo.c
gcc -std=gnu17 -mtune=corei7 -flto -fopenmp -pthread -Wall -pedantic -O3 -I../include -c -o bar.o bar.c
gcc -std=gnu17 -mtune=corei7 -flto -fopenmp -pthread -Wall -pedantic -O3 -I../include -c -o baz.o baz.c
ar -rcs libfoo.a foo.o bar.o baz.o
ar -t libfoo.a
foo.o
bar.o
baz.o
touch -c libfoo.a

---------------------------------- show the current status ---------------------

$ ls -l
total 84
-rw-rw-r-- 1 greg21 greg21  3742 Dec  9 14:02 bar.c
-rw-rw-r-- 1 greg21 greg21 10256 Dec  9 14:03 bar.o
-rw-rw-r-- 1 greg21 greg21  3916 Dec  9 14:02 baz.c
-rw-rw-r-- 1 greg21 greg21 12616 Dec  9 14:03 baz.o
-rw-rw-r-- 1 greg21 greg21  3220 Dec  9 14:02 foo.c
-rw-rw-r-- 1 greg21 greg21  6456 Dec  9 14:03 foo.o
-rw-rw-r-- 1 greg21 greg21 29684 Dec  9 14:03 libfoo.a
-rw-rw-r-- 1 greg21 greg21   618 Dec  9 13:58 Makefile

Now make sure that libfoo.a is newer than everything else

$ touch libfoo.a
$ ls -l
total 84
-rw-rw-r-- 1 greg21 greg21  3742 Dec  9 14:02 bar.c
-rw-rw-r-- 1 greg21 greg21 10256 Dec  9 14:03 bar.o
-rw-rw-r-- 1 greg21 greg21  3916 Dec  9 14:02 baz.c
-rw-rw-r-- 1 greg21 greg21 12616 Dec  9 14:03 baz.o
-rw-rw-r-- 1 greg21 greg21  3220 Dec  9 14:02 foo.c
-rw-rw-r-- 1 greg21 greg21  6456 Dec  9 14:03 foo.o
-rw-rw-r-- 1 greg21 greg21 29684 Dec  9 14:04 libfoo.a
-rw-rw-r-- 1 greg21 greg21   618 Dec  9 13:58 Makefile

Re-issue make. It does not rebuild the .o files, then Why does it not say that libfoo.a is uptodate ?

$ make
ar -rcs libfoo.a foo.o bar.o baz.o
ar -t libfoo.a
foo.o
bar.o
baz.o
touch -c libfoo.a
    

Solution

  • The recipe for your target called library does not create a file called library, so the target is always out of date. Turn library into $(LIBRARY) and the target will actually be your libfoo.a file and its timestamp will be considered.

    $(LIBRARY) : $(OBJS)
        ar -rcs $(LIBRARY) $?
        ar -t $(LIBRARY)
        touch -c $(LIBRARY)