I haven't been doing a lot of C programming lately, but recently I revisited an old project and found the old Makefile to build a library under FreeBSD no longer works. Here's a much simplified version of the Makefile that used to work:
TEST = Test
LIBTEST = lib$(TEST).a
CC = cc
.PRECIOUS: $(LIBTEST)
all: $(LIBTEST)
LIBSRC = test.c
# Do not automatically delete library source files
.SECONDARY: $(LIBSRC)
LIBOBJ = $(LIBSRC:%.c=%.o)
$(LIBTEST): $(LIBTEST)($(LIBOBJ))
$(AR) $(ARFLAGS) $@ $?
rm -f $?
clean:
@rm -f *.o $(LIBTEST)
And here's a trivial C program to go with it:
/* test.c */
#include <stdio.h>
int
test(char const *text)
{
printf("%s\n", text);
return 1;
}
It looks like the Makefile directive dependency:
$(LIBTEST): $(LIBTEST)($(LIBOBJ))
no longer works. It results in:
ar -crD libTest.a
rm -f
I've been perusing 'man make' without success.
One thing that puzzles me is that 'man make' says "For a more thorough description of make and makefiles, please refer to PMake - A Tutorial."
Is this accurate? I was under the impression that pmake was replaced by bsdmake in recent versions of FreeBSD - is this the source of my problems?
Note: I am not interested in answers that boil down to "you can do this just fine using GNU make" - this is a question for FreeBSD make.
suggests that prerequisite of
$(LIBTEST)
(herelibTest.a
) is a$(LIBOBJ)
(heretest.o
) member of that archive, which I am not really sure whatmake
would be supposed to conclude from, but for me (FreeBSD 11.0) it comes up withall
(which really meanslibTest.a
) is already up to date (see also an example below the ruler). Changing the line to:Would seem to make sense (and unless I've missed something, should be what you want), an object file is prerequisite of the library target and rule updates the library with all prerequisites newer then the target (
$?
).Which leads me to one more comment. That
rm
seems not only unnecessary, but actually harmful, because it meanstest.o
always gets recompiled on invocation ofmake all
and library always gets updated even there is no source (test.c
) change as the intermediate prerequisite target is not there (i.e. out of date).I'd really get that behavior even if I resolve all the stuff around and strip that
Makefile
to a bare minimum: