It seems that you can pass the /path/to/libfoo.so as input file to gcc and program will be linked correctly with it, just as when using -lfoo option in combination with -L/path/to.
In case I know the full path of needed version of library, what is the difference?
If you're certain you know the right path to the right library, and the library is a static archive, /path/to/libfoo.a, then there's no difference, but for a shared library it makes a difference.
If you run ldd and/or readelf on your executable you'll see the the linker has added a dependency to the library at that specific location, e.g. here's a link using -L and -l:
$ g++ main.cc -lfoo -L.
$ readelf -d ./a.out | fgrep libfoo
0x0000000000000001 (NEEDED) Shared library: [libfoo.so]
$ ldd ./a.out
linux-vdso.so.1 => (0x00007fff9b1fa000)
libfoo.so => not found
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003ebe200000)
libm.so.6 => /lib64/libm.so.6 (0x0000003ebc200000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003ebd200000)
libc.so.6 => /lib64/libc.so.6 (0x0000003ebbe00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003ebba00000)
Note that the dependency is just libfoo.so (and is not found because . isn't in my shared library search path, ignore that for now.)
Here's the same test, but using the pathname of the library:
$ g++ main.cc /dev/shm/libfoo.so
$ readelf -d ./a.out | fgrep libfoo
0x0000000000000001 (NEEDED) Shared library: [/dev/shm/libfoo.so]
$ ldd ./a.out
linux-vdso.so.1 => (0x00007fff963f4000)
/dev/shm/libfoo.so (0x00007fad91c48000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003ebe200000)
libm.so.6 => /lib64/libm.so.6 (0x0000003ebc200000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003ebd200000)
libc.so.6 => /lib64/libc.so.6 (0x0000003ebbe00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003ebba00000)
Notice that now the dependency is /dev/shm/libfoo.so.
This means that your program will fail to find the library at run-time if it isn't installed in the same location on your development machine and the machine where you plan to run it.
However, this only applies if the library does not have a SONAME, if I relink the library specifying a soname (with the linker's -h option) and then relink my executable, the dependency uses the library's soname, even if I specify a full path:
$ g++ -shared foo.cc -o libfoo.so -Wl,-h,libfoo.so
$ readelf -d libfoo.so | fgrep libfoo
0x000000000000000e (SONAME) Library soname: [libfoo.so]
$ g++ main.cc /dev/shm/libfoo.so
$ readelf -d ./a.out | fgrep libfoo
0x0000000000000001 (NEEDED) Shared library: [libfoo.so]
To really demonstrate the dependency uses the soname, we can give it a soname that doesn't match the filename at all:
$ g++ -shared foo.cc -o libfoo.so -Wl,-h,libbar.so
$ readelf -d libfoo.so | fgrep SONAME
0x000000000000000e (SONAME) Library soname: [libbar.so]
$ g++ main.cc /dev/shm/libfoo.so
$ readelf -d ./a.out | fgrep libbar
0x0000000000000001 (NEEDED) Shared library: [libbar.so]
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