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:
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
Thanks for all the responses! I learned a lot about libraries. I'd like to put all the responses as the accepted answer :-)
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.
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.
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.
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.
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
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With