Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use LDFLAGS in makefile

I am new to Linux OS. I am trying to compile a .c file using a makefile. The math library has to be linked. My makefile looks like this:

CC=gcc CFLAGS=-Wall -lm  all:client  .PHONY: clean clean:     rm *~ *.o client 

When I run make, I get the following error:

"undefined reference to rint" 

So it is not able to link the math library.

But when I compile explicitly using

gcc client.c -lm -o client 

it successfully compiles.

So how should I change my makefile such that it works. I have already tried adding LDFLAGS=-lm. But I get the same error.

I should also add that when I run make, it expands to

gcc -Wall -lm client.c -o client 

(notice that when I run gcc explicitly with -lm at the end, it works).

like image 592
user1802785 Avatar asked Nov 06 '12 11:11

user1802785


People also ask

What are Ldflags in makefile?

LDFLAGS: Extra flags to give to compilers when they are supposed to invoke the linker, 'ld', such as -L. Libraries (-lfoo) should be added to the LDLIBS variable instead.

How do I include a file in a makefile?

In addition, if you want to dynamically link libraries, you need to tell the linker where they are. -L/dir/containing -lc . If you don't want to set a LD_LIBRARY_PATH when executing, you'll need to set rpath , -Wl,--rpath=/path/containing .

How do I create a library path in makefile?

Like that, you can set a default search path for the binary. Looks like you even already use -rpath in your makefile, but you specify the wrong path: LIBS = -L$(LIB) -lfuse -lsqlite3 -lkw_taglib -ltag_c -ltag -Wl,-rpath=. So the binary will search in the current directory for dyn-libraries.


2 Answers

Your linker (ld) obviously doesn't like the order in which make arranges the GCC arguments so you'll have to change your Makefile a bit:

CC=gcc CFLAGS=-Wall LDFLAGS=-lm  .PHONY: all all: client  .PHONY: clean clean:     $(RM) *~ *.o client  OBJECTS=client.o client: $(OBJECTS)     $(CC) $(CFLAGS) $(OBJECTS) -o client $(LDFLAGS) 

In the line defining the client target change the order of $(LDFLAGS) as needed.

like image 132
Makkes Avatar answered Sep 28 '22 18:09

Makkes


In more complicated build scenarios, it is common to break compilation into stages, with compilation and assembly happening first (output to object files), and linking object files into a final executable or library afterward--this prevents having to recompile all object files when their source files haven't changed. That's why including the linking flag -lm isn't working when you put it in CFLAGS (CFLAGS is used in the compilation stage).

The convention for libraries to be linked is to place them in either LOADLIBES or LDLIBS (GNU make includes both, but your mileage may vary):

LDLIBS=-lm 

This should allow you to continue using the built-in rules rather than having to write your own linking rule. For other makes, there should be a flag to output built-in rules (for GNU make, this is -p). If your version of make does not have a built-in rule for linking (or if it does not have a placeholder for -l directives), you'll need to write your own:

client.o: client.c     $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<  client: client.o     $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
like image 32
laindir Avatar answered Sep 28 '22 18:09

laindir