Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - undefined reference to "sqrt" even with '-lm'

Tags:

c

gcc

math.h

ld

I try to compile a library in C that need "math.h", here is the begining of the .c file:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h> 
#include "sparse_matrix.h"
...

and I compile with this command:

gcc -c ./sparse_matrix.c -o sparse_matrix.o -lm -Wall -pedantic -std=c99 -g -O

But even with the #include done and the flag -lm after the file (I've tried at the end of the line but nothing changed) I still get the error: undefined reference to « sqrt » collect2: error: ld returned 1 exit status

I don't get it after an hour of googling the issue. I'm working with gcc 4.9 under ubuntu 14.10 (utopic unicorn). Thank for any help in advance!

like image 322
Alexandre Pieroux Avatar asked Dec 15 '14 00:12

Alexandre Pieroux


1 Answers

I don't think that is the command you're running (well, it may be one of them, but it's certainly not the one causing your error).

The -c option to gcc tells it to only create the object files (and you're specifically sending the output to sparse_matrix.o, an object file rather than an executable one).

In that case, the linker should not be called at all.

In fact, with a dummy sparse_matrix.c of:

#include <math.h>
int main(void) {
    return (int)(sqrt(16.0));
}

your command works fine and, when I complete the process with:

pax> gcc -o sparse_matrix sparse_matrix.o -lm
pax> ./sparse_matrix
pax> echo $?
4

you can see that it also runs just fine.

It may be that you're leaving off the linker flags (such as -lm) from the actual link stage, which would cause this problem. They should have no effect on the compilation stage (unless they affect both compile and link stages but -l isn't one of those).

And, by "leaving off", I also include the possibility of "misplacing". Some linkers are positional in the way they handle libraries in that they will only extract objects from libraries if they satisfy an undefined symbol at the point where they're listed.

So, the command:

linker sparse_matrix.o -lm ...

would work because the .o file introduces an unsatisfied reference to sqrt, which is satisfied by libm. If your linker is positional, then:

linker -lm sparse_matrix.o ...

wouldn't work because, at the time of processing libm, there were no unsatisfied symbols so nothing was extracted. The undefined reference to sqrt is then introduced after that point and there are no other objects or libraries to satisfy it.

Whether ld or the gcc linker stage has that limitation, I don't know, I'm just raising the possibility as something to watch out for.

like image 80
paxdiablo Avatar answered Sep 22 '22 13:09

paxdiablo