1

Possible Duplicate:
Linker errors when compiling against glib…?

Okay, I know this may be a duplicate, but I can't find any other answer to my problem. I am trying to install Pintos and when I run 'make' in the src/utils directory, I get the error that there is an undefined reference to 'floor'. I checked the makefile and here's what I got:

all: setitimer-helper squish-pty squish-unix
# 2207718881418

CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o

clean: 
    rm -f *.o setitimer-helper squish-pty squish-unix

I tried adding LIBS = -lm but that didn't help.

Output of make:

gcc -lm  setitimer-helper.o   -o setitimer-helper
setitimer-helper.o: In function `main':
setitimer-helper.c:(.text+0xbb): undefined reference to `floor'
collect2: ld returned 1 exit status
make: *** [setitimer-helper] Error 1

Any solutions to this dilemma?

Community
  • 1
  • 1
varagrawal
  • 2,909
  • 3
  • 26
  • 36
  • 3
    I can't see the full compiler command but libraries need to go at the end. See http://stackoverflow.com/questions/9966959/linker-errors-when-compiling-against-glib/9966989#9966989 – hmjd Dec 16 '12 at 10:35
  • I am sorry, but don't think that helps. I simply run a make and it gives me that error. – varagrawal Dec 16 '12 at 10:38
  • Can you post the output of make, particularly the `gcc` line? – hmjd Dec 16 '12 at 10:39
  • hmjd please see the question again. – varagrawal Dec 16 '12 at 10:47
  • 5
    In the output from `make`, notice the `-lm` is _not_ at the end of the compiler command. The problem is as I stated in my earlier comment. – hmjd Dec 16 '12 at 10:51
  • So how do I change that? I am not very knowledgeable about the Makefile. – varagrawal Dec 16 '12 at 11:42
  • Varagrawal's _issue_ is that `-lm` is not at the end of the command as per @hmjd's suggested similar question, but his _question_ is about how to fix it while minimising changes to his makefile -- which the suggested duplicate doesn't address at all. For actual duplicate questions, look at http://stackoverflow.com/questions/9963645/getting-undefined-reference-to-floor-on-running-make-in-pintos or http://stackoverflow.com/questions/10539153/how-to-follow-linking-order-when-linking-against-static-library-with-gnu-make – John Marshall Dec 16 '12 at 22:39
  • John Marshall, your first link is the exact duplicate. I couldn't find that on earlier searches maybe due to the lack of a PintOS tag, so thanks for it. And I had mentioned that my question may be a duplicate in the first line. ;-) :-) – varagrawal Dec 17 '12 at 10:29

2 Answers2

6

Your original makefile defines a bunch of variables

CC = gcc
# etc

and lists some dependencies

setitimer-helper: setitimer-helper.o
# etc

but doesn't have any recipes giving the exact commands to be used to remake the targets, except for the clean rule. This means that built-in implicit rules will be used; e.g., to link setitimer-helper the following built-in rule will be used:

$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

For setitemer-helper, the automatic variables are filled in using the relevant dependency:

$(CC) $(LDFLAGS) setitimer-helper.o $(LDLIBS) -o setitimer-helper

and from this you can see how the remaining variables -- $(CC), $(LDFLAGS), and $(LDLIBS) -- were filled in to give the output of make that you saw.

As various people have noted, you need to make sure that -lm goes at the end of the link command so that it can be used to satisfy references to library functions like floor(). At the moment, your makefile sets $(LDFLAGS) to -lm, but that variable is used at the start of the link command.

The conventional variables are set up in this built-in rule so that LDFLAGS can be used for options (a.k.a. "flags") that (historically) need to be at the start of the link command, and LDLIBS can be used for libraries that need to be specified after the *.o object files.

So to fix this in terms of the makefile you are using, you need to remove -lm from the LDFLAGS variable that is defined, and instead add another variable definition for LDLIBS:

LDLIBS = -lm

(I'm oversummarising slightly: the built-in rule also contains $(TARGET_ARCH) and $(LOADLIBES), but those aren't of interest here.)

John Marshall
  • 6,815
  • 1
  • 28
  • 38
1

It's compiled in wrong order, the way to proceed is:

CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm

myprog: myprog.o more_code.o
       ${CC} ${CFLAGS} myprog.o more_code.o ${LDFLAGS} -o myprog

myprog.o: myprog.c
       ${CC} ${CFLAGS} -c myprog.c

more_code.o: more_code.c
       ${CC} ${CFLAGS} -c more_code.c

clean:
       \rm myprog.o more_code.o myprog 

More info: http://www.physics.utah.edu/~p5720/rsrc/make.html

Can you show me in terms of the original makefile? I can try :)

CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
OBJECTS = setitimer-helper.o squish-pty.o squish-unix.o

all: setitimer-helper

setitimer-helper: $(OBJECTS)
       ${CC} ${CFLAGS} $(OBJECTS) ${LDFLAGS} -o setitimer-helper

setitimer-helper.o: setitimer-helper.c
       ${CC} ${CFLAGS} -c setitimer-helper.c

squish-pty.o: squish-pty.c
       ${CC} ${CFLAGS} -c squish-pty.c

squish-unix.o: squish-unix.c
       ${CC} ${CFLAGS} -c squish-unix.c

And since you are new to Makefile, it's a good idea to add -Wextra -pedantic to CFLAGS

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • I am not getting you. The makefile was given to me as part of a tarball. Can you show me in terms of the original makefile? – varagrawal Dec 16 '12 at 11:44
  • @Varagrawal instead of `$(LD) $(LDFLAGS) myprog.o -o myprog`, write `$(LD) myprog.o $(LDFLAGS) -o myprog`, so that the libraries go after the list of object files to be linked. –  Dec 16 '12 at 11:45
  • But that is not the way the Makefile was originally structured, and since I am new to makefiles, I have no clue how to make the correct changes. – varagrawal Dec 16 '12 at 11:51
  • Using LDLIBS instead of LDFLAGS should solve the problem without having to explicitly listing recipes for all targets (using implicit rules). @john-marshall shows how to do that. – Rudy Matela Nov 29 '13 at 14:57
  • @RudyMatela, you are right, but I am just pointing the cause of error – David Ranieri Nov 29 '13 at 19:02