I'm trying to make a simple as possible make file that uses the math library (fmax below, the rest is C cruft for this examlpe):
easy.c:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, const char *argv[]) {
double x=atof(argv[1]);
double y=atof(argv[2]);
double z=fmax(x,y);
printf("max(%f,%f)=%f\n",x,y,z);
return 0;
}
Makefile:
CFLAGS=-g
LDFLAGS=-lm
easy : easy.c
However this creates a link error (missing fmax). This is because make places the LDFLAGS first in the compile line:
> make easy
cc -g -lm easy.c -o easy
/usr/bin/ld: /tmp/ccmN5G9c.o: in function `main':
/home/user/projects/easy/easy.c:8: undefined reference to `fmax'
collect2: error: ld returned 1 exit status
make: *** [<builtin>: easy] Error 1
Of course, if I explicitly put the LDFLAGS at the end using an explicit rule, it works:
CFLAGS=-g
LDFLAGS=-lm
easy : easy.c
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
Of course, understanding the Makefile is not nearly so easy now. Does anyone have a reason why the default rule does not put the link line at the end? Or is there an "easy" make that does allow a newcomer to link a number of source files into one executable (no lingering .o files)?
CodePudding user response:
You should be using LDLIBS
not LDFLAGS
. LDFLAGS
is for linker flags (such as -L
). LDLIBS
is for linker libraries (such as -lm
).
If you investigate the default rules (make -pf/dev/null
) you'll find this one:
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
%: %.o
# recipe to execute (built-in):
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
(Ignore LOADLIBES
as that's a deprecated name). Also see the documentation for LDLIBS
and LDFLAGS
.