11

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!

Alexandre Pieroux
  • 219
  • 1
  • 2
  • 13
  • The `-c` option suppresses linking. You won't get that error from that command line. Therefore, that isn't the command line that produces the error. (Don't use @ before rules in a `makefile` — it probably isn't your problem, but it hides commands and can mislead you.) And most of this is what @paxdiablo said. – Jonathan Leffler Dec 15 '14 at 01:06
  • possible duplicate of ["undefined reference to \`pow'" even with math.h and the library link -lm](http://stackoverflow.com/questions/16344445/undefined-reference-to-pow-even-with-math-h-and-the-library-link-lm) – Ciro Santilli OurBigBook.com May 15 '15 at 20:36

1 Answers1

13

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.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Thank! In fact with the '-c' flag the linker is not called at all, it was a mistake. But I tried without the -c flag (gcc sparse_matrix.c -o sparse_matrix.o -Wall -pedantic -std=c99 -g -O -lm). But I've got an undefined reference to "main". As I said I only try to do a library "sparse_matrix" that need "sqrt" function from "libmath". – Alexandre Pieroux Dec 15 '14 at 01:36
  • 1
    @Alex, check if there actually _is_ a `main` in that C file. Given you're separating compilation from link stages, it's likely that it exists in _another_ C file. If you're _only_ creating a library with objects (no `main`), `-c` is the way to go, but the bringing in of the math lib is something that should be done during linking, when a client of yours needs to use your stuff: `gcc client_stuff.c -lsparse_matrix_lib -lm ...`. – paxdiablo Dec 15 '14 at 01:40
  • Yes that's what I was trying to do. Thank, I'm not that ease with library and I thought I could link a lib into another. Sorry for this rather simple mistake. I just tried with my main program which use this library and (now that I understand that) it work fine (just added '-lm' NOT at the compilation time of the library but at the linking stage of the program using my lib) :) Thank again for such quick answers! – Alexandre Pieroux Dec 15 '14 at 01:50