Using Shared Libraries in C
When you are making applications in C, it’s inevitable to use shared libraries. Either system-wide or application-specific. Searching libraries occurs at linking stage or runtime stage. Where does the compiler look for the header files and the dynamic libraries? It varies on different platforms.
1. Include directories
Print the standard include directories.
On Linux.
echo | gcc -x c -E -Wp,-v - > /dev/null
On macOS.
echo | clang -x c -E -Wp,-v - > /dev/null
In addition to standard directories, you can pass the -I<directory> option to
the compiler, which can add the specified directory to the search path for include
files.
2. Library directories
On Linux, show default library search directories by run the following command.
ld --verbose | grep SEARCH_DIR | tr ' ;' \\012 |
2.1. macOS install names
On macOS, the mannual page man dyld describes the default directories that
contain libraries, along with the related environment variables.
It’s worth noting that each shared library has an "install name", the path at which it is expected to be found during runtime. Change "install name" by two means:
Compile the library with correct install name (ether with
-Wl,-install_name,/path/to/libor outright-o /path/to/lib), then compile the main binary to link against it.Use
install_name_tool. This ia a bit more involved.
There is a detailed explaination about "install name" by Siguza on Stackoverflow.
2.2. Insert library directory into the executable
So far, we have two methods of informing the dynamic linker (DL) of location of a library:
Environment variables, e.g.
LD_LIBRARY_PATH.Installing library in one of the standard directories.
Third method: during static linking, we can insert a list of directories into the executable.
A "run-time library path (
rpath) list".At run time, DL will search listed directories to resolve dynamic dependencies.
Useful if libraries will reside in locations that are fixed, but not in standard list.