0

What is the purpose of specifying library dependencies with gcc?

I have written a shared library, libPulse_IO.so, that calls functions from both libusb-1.0.so and libpcap.so.

i.e. in pulse_IO.c there is stuff like:

#include <libusb-1.0/libusb.h>
#include <pcap.h>

ret = libusb_init(&pdw_io->context);

pdw_io->pcap=pcap_open_live(pdw_io->eth_name, ETH_SNAPLEN, ETH_PROMISCUOUS, ETH_TIMEOUT, pcap_errbuf);

Now when I come to build my library, I notice that it seems to make no difference if I specify -l libusb-1.0 -l pcap in the call to gcc

i.e. I can run (no mention of -l usb-1.0 or -l pcap):

gcc -fPIC -g -Wall -fvisibility=hidden  -I../../../g2/src -I../../core/src    pulse_IO.c -c -o ../build/linux/debug/pulse_IO.o
gcc -fPIC -g -Wall -fvisibility=hidden  -I../../../g2/src -I../../core/src    -shared -Wl,-soname,libPulse_IO_dbg.so ../build/linux/debug/pulse_IO.o -o ../build/linux/debug/libPulse_IO_dbg.so

or (-l usb-1.0 or -l pcap specified):

gcc -fPIC -g -Wall -fvisibility=hidden  -I../../../g2/src -I../../core/src  -lusb-1.0 -lpcap  pulse_IO.c -c -o ../build/linux/debug/pulse_IO.o
gcc -fPIC -g -Wall -fvisibility=hidden  -I../../../g2/src -I../../core/src  -lusb-1.0 -lpcap  -shared -Wl,-soname,libPulse_IO_dbg.so ../build/linux/debug/pulse_IO.o ../build/linux/debug/shared.o -o ../build/linux/debug/libPulse_IO_dbg.so

Both instances build without error.

Running ldd in both cases yields the same output:

ldd ../build/linux/debug/libPulse_IO_dbg.so 
    linux-vdso.so.1 =>  (0x00007ffea93ee000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd43af68000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fd43b53f000)

No mention of a dependency on libusb-1.0.so or libpcap.so - how?

Examining the shared library produced in both instances shows that there are undefined references to the libusb and pcap functions, i.e.

nm ../build/linux/debug/libPulse_IO_dbg.so 
                 U __assert_fail@@GLIBC_2.2.5
                 U atof@@GLIBC_2.2.5
                 U atoi@@GLIBC_2.2.5
...
                 U libusb_init
                 U libusb_kernel_driver_active
                 U libusb_open_device_with_vid_pid
...
                 U pcap_open_live
                 U pcap_perror
                 U pcap_sendpacket
                 U pcap_setfilter

So the library is built in both instances, with or without the -l library specifiers, and in both instances we can see calls to the libusb-1.0 and libpcap functions in the symbol table.

Which brings me back to my original question.. what is the purpose of specifying library dependencies with gcc?

My expectation was that the calls to gcc would have failed without specifying the libusb-1.0 and libpcap library dependencies?

bph
  • 10,728
  • 15
  • 60
  • 135
  • 2
    Possible duplicate of [Why does the order in which libraries are linked sometimes cause errors in GCC?](https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc) You have specified `-lusb-1.0 -lpcap` incorrectly so they got effectively ignored, this is why you don't see a difference between the two cases. Move `-lusb-1.0 -lpcap` to the end of the command line. – n. m. could be an AI Jan 05 '18 at 18:51
  • hmm - now you mention it i have come across this issue before, so I can believe that the library specifiers get ignored, but how does it then build? If there is no compile/link time requirement to specify the library dependencies, why would you ever specify them? – bph Jan 08 '18 at 11:28
  • 1
    A shared library can by default have undefined symbols, it's not an error. These undefined symbols will be resolved at load time with symbols from the executable or other shared libraries. Here comes the problem: if you don't specify the dependencies correctly, and no other module pulls them in, you will end up with a load error. Try to run a program built against your library and you will see. – n. m. could be an AI Jan 08 '18 at 11:48
  • this is my confusion, my app that uses my library clearly works, in as much as its happily connecting and sending receiving packets over usb/ethernet.. I'm sure you're right though and there must be something i've overlooked.. – bph Jan 08 '18 at 11:53
  • 1
    Please roll back everything ;) What I have said re. link order is good w.r.t. static libraries, NOT shared libraries! When you link against a shared library, `-l` is not ignored regardless of where in the command line it is used. However the dependency WILL be recorded in the resulting file, so your claim "Running ldd in both cases yields the same output" seems incorrect (or at any rate I could not reproduce it). – n. m. could be an AI Jan 08 '18 at 12:12
  • well just to add to the intrigue, when doing a native build under linux (as described in the OP) works with and without. Crossbuilding for win32 using mingw fails when the lib dependencies aren't specified, i.e. the behaviour I would expect. Curiouser and curiouser? – bph Jan 08 '18 at 13:03
  • there is the 'if its not broke don't fix it' argument, but having something work while at the same time thinking, 'this shouldn't work' doesn't sit well with me? – bph Jan 08 '18 at 13:10
  • Windows DLLs cannot have unresolved symbols, Linux shared libraries can. – n. m. could be an AI Jan 08 '18 at 13:45

0 Answers0