Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linker woes - undefined reference

Tags:

gcc

linker

I'm having a problem with my compiler telling me there is an 'undefined reference to' a function I want to use in a library. Let me share some info on the problem:

  • I'm cross compiling with gcc for C.
  • I am calling a library function which is accessed through an included header which includes another header, which contains the prototype.
  • I have included the headers directory using -I and i'm sure it's being found.
  • I'm first creating the .o files then linking them in a separate command.

So my thought is it might be the order in which I include the library files, but i'm not sure what is the correct way to order them. I tried with including the headers folder both before and after the .o file.

Some suggests would be great, and maybe and explanation of how the linker does its thing.

Thanks!


Response to answers

  • there is no .a library file, just .h and .c in the library, so -l isn't appropriate
  • my understanding of a library file is that it is just a collection of header and source files, but maybe it's a collection of .o files created from the source?!
  • there is no library object file being created, maybe there should be?? Yes seems I don't understand the difference between includes and libraries...i'll work on that :-)

Thanks for all the responses! I learned a lot about libraries. I'd like to put all the responses as the accepted answer :-)

like image 461
Richard Avatar asked Sep 27 '08 12:09

Richard


People also ask

How do you resolve an undefined reference?

The error: undefined reference to function show() has appeared on the terminal shell as predicted. To solve this error, simply open the file and make the name of a function the same in its function definition and function call.

How do you fix a linker error?

You can fix the errors by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass . obj files or . lib files that contain the definitions to the linker.

What causes a linker error?

Linker errors occur when the linker is trying to put all the pieces of a program together to create an executable, and one or more pieces are missing. Typically, this can happen when an object file or libraries can't be found by the linker. Fixing linker errors can be tricky.

How do you fix undefined symbol in C++?

Generating an Executable Output File Similarly, if a shared object is used to create a dynamic executable and leaves an unresolved symbol definition, an undefined symbol error results. To allow undefined symbols, as in the previous example, use the link-editor's -z nodefs option to suppress the default error condition.


3 Answers

Headers provide function declarations and function definitions. To allow the linker find the function's implementation (and get rid of the undefined reference) you need to ask the compiler driver (gcc) to link the specific library where the function resides using the -l flag. For instance, -lm will link the math library. A function's manual page typically specifies what library, if any, must be specified to find the function.

If the linker can't find a specified library you can add a library search path using the -L switch (for example, -L/usr/local/lib). You can also permanently affect the library path through the LIBRARY_PATH environment variable.

Here are some additional details to help you debug your problem. By convention the names of library files are prefixed with lib and (in their static form) have a .a extension. Thus, the statically linked version of the system's default math library (the one you link with -lm) typically resides in /usr/lib/libm.a. To see what symbols a given library defines you can run nm --defined-only on the library file. On my system, running the command on libm.a gives me output like the following.

e_atan2.o:
00000000 T atan2

e_asinf.o:
00000000 T asinf

e_asin.o:
00000000 T asin

To see the library path that your compiler uses and which libraries it loads by default you can invoke gcc with the -v option. Again on my system this gives the following output.

GNU assembler version 2.15 [FreeBSD] 2004-05-23 (i386-obrien-freebsd) 
using BFD version 2.15 [FreeBSD] 2004-05-23
/usr/bin/ld -V -dynamic-linker /libexec/ld-elf.so.1 /usr/lib/crt1.o 
/usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /var/tmp//ccIxJczl.o -lgcc -lc 
-lgcc /usr/lib/crtend.o /usr/lib/crtn.o
like image 96
Diomidis Spinellis Avatar answered Sep 28 '22 00:09

Diomidis Spinellis


It sounds like you are not compiling the .c file in the library to produce a .o file. The linker would look for the prototype's implementation in the .o file produced by compiling the library

Does your build process compile the library .c file?

Why do you call it a "library" if it's actually just source code?

like image 20
Peter K. Avatar answered Sep 27 '22 23:09

Peter K.


I fear you mixed the library and header concepts. Let's say you have a library libmylib.a that contains the function myfunc() and a corresponding header mylib.h that defines its prototype. In your source file myapp.c you include the header, either directly or including another header that includes it. For example:

/* myapp.h
** Here I will include and define my stuff
*/
...
#include "mylib.h"
...

your source file looks like:

/* myapp.c
** Here is my real code
*/
...
#include "myapp.h"
...
/* Here I can use the function */
myfunc(3,"XYZ");

Now you can compile it to obtain myapp.o:

gcc -c -I../mylib/includes myapp.c

Note that the -I just tells gcc where the headers files are, they have nothing to do with the library itself!

Now you can link your application with the real library:

gcc -o myapp -L../mylib/libs myapp.o -lmylib

Note that the -L switch tells gcc where the library is, and the -l tells it to link your code to the library.

If you don't do this last step, you may encounter the problem you described.

There might be other more complex cases but from your question, I hope this would be enough to solve your problem.

like image 45
Remo.D Avatar answered Sep 27 '22 23:09

Remo.D