Undefine reference for libraries, so How could I find the right path?

Guilherme Longo picture Guilherme Longo · Aug 20, 2013 · Viewed 7.1k times · Source

I am trying to compile a v4l2 example in Ubuntu but I am getting the following error:

guilherme@notedev01:~/Downloads/V4l2_samples-0.4.1$ make
gcc -O2  -L/usr/include -lX11 -lXext -o viewer viewer.c
/tmp/ccUjnjWQ.o: In function `image_destroy':
viewer.c:(.text+0x234): undefined reference to `XDestroyImage'
viewer.c:(.text+0x256): undefined reference to `XFreeGC'
viewer.c:(.text+0x277): undefined reference to `XShmDetach'
viewer.c:(.text+0x2ac): undefined reference to `XFreePixmap'
/tmp/ccUjnjWQ.o: In function `image_create':
viewer.c:(.text+0x305): undefined reference to `XCreateGC'
viewer.c:(.text+0x31d): undefined reference to `XGetWindowAttributes'
viewer.c:(.text+0x39e): undefined reference to `XShmCreateImage'
viewer.c:(.text+0x3f5): undefined reference to `XShmAttach'
viewer.c:(.text+0x44e): undefined reference to `XCreateImage'
viewer.c:(.text+0x494): undefined reference to `XShmQueryExtension'
viewer.c:(.text+0x4b4): undefined reference to `XShmPixmapFormat'
viewer.c:(.text+0x4dc): undefined reference to `XShmCreatePixmap'
/tmp/ccUjnjWQ.o: In function `image_put':
viewer.c:(.text+0x54c): undefined reference to `XPutImage'
viewer.c:(.text+0x586): undefined reference to `XShmPutImage'
/tmp/ccUjnjWQ.o: In function `main':
viewer.c:(.text.startup+0x18b): undefined reference to `XOpenDisplay'
viewer.c:(.text.startup+0x1b1): undefined reference to `XScreenOfDisplay'
viewer.c:(.text.startup+0x1ee): undefined reference to `XCreateSimpleWindow'
viewer.c:(.text.startup+0x249): undefined reference to `XMapRaised'
viewer.c:(.text.startup+0x263): undefined reference to `XStoreName'
viewer.c:(.text.startup+0x280): undefined reference to `XGetWindowAttributes'
viewer.c:(.text.startup+0x92f): undefined reference to `XPending'
viewer.c:(.text.startup+0x94c): undefined reference to `XNextEvent'
viewer.c:(.text.startup+0xaee): undefined reference to `XPending'
viewer.c:(.text.startup+0xb0b): undefined reference to `XNextEvent'
viewer.c:(.text.startup+0xf39): undefined reference to `XPending'
viewer.c:(.text.startup+0xf56): undefined reference to `XNextEvent'
collect2: error: ld returned 1 exit status
make: *** [viewer] Error 1

What I can see is that the path for -lx11 and -lXext isn't -L/usr/include. How can I find the right path for those libraries?

Thanks.

Answer

umläute picture umläute · Aug 22, 2013

as Chris has pointed out, the order is wrong, you need to put the -lX11 -lXext after the source-code/object-files.

this is because modern compilers try to optimize the final result and not link against unused libraries. they do so by maintaining a list of unresolved symbols within an object and use any binary files that come aferwards in the linker arguments to resolve those symbols.

example

your program test uses the function do_foo() from libfoo and the function do_bar_do() from libbar.

you link it using:

$ gcc -o test test.o -lfoo -lbar

the linker first searches test.o and notices that some symbols (do_foo and do_bar_do) are not defined anywhere. it then proceeds to libfoo (specified right after test.o) and finds that it provides do_foo, so it creates code to use it from your program. do_bar_do is still unresolved, until the linker checks upon libbar.

consider doing it the wrong way:

$ gcc -o test -lfoo test.o -lbar

the linker will first check libfoo and see that it doesn't contain any unresolved symbols. cool. it will then proceed to test.o and notice do_bar_do and do_foo. do_bar_do is resolved by the right-hand libbar but do_foo is not resolved at all, and you get an error:

undefined reference to `do_foo'

"but the code is meant to be a tutorial..."

so why is it not working?

older compilers where a bit lax about the order of dependencies (they would check all binaries/libraries/objects whether a given symbol could be resolved); that's why you can still find code out there that puts the libraries to link against before the object files.