The linker searches for libraries at several locations and in a certain prescribed order. Some of these locations are standard paths, while others depend on the compiler options -Rpath, -llibrary, and -Ldir and the environment variable LD_LIBRARY_PATH.
The standard library search paths used by the linker are determined by the installation path, and they differ for static and dynamic loading. A standard install puts the Sun Studio compiler software under /opt/SUNWspro/.
While building the executable file, the static linker searches for any libraries in the following paths (among others), in the specified order:
/opt/SUNWspro/lib |
Sun Studio shared libraries |
/usr/ccs/lib/ |
Standard location for SVr4 software |
/usr/lib |
Standard location for UNIX software |
These are the default paths used by the linker.
The dynamic linker searches for shared libraries at runtime, in the specified order:
Paths specified by user with -Rpath
/opt/SUNWspro/lib/
/usr/lib standard UNIX default
The search paths are built into the executable.
Use the LD_LIBRARY_PATH environment variable to specify directory paths that the linker should search for libraries specified with the -llibrary option.
Multiple directories can be specified, separated by a colon. Typically, the LD_LIBRARY_PATH variable contains two lists of colon-separated directories separated by a semicolon:
dirlist1;dirlist2
The directories in dirlist1 are searched first, followed by any explicit -Ldir directories specified on the command line, followed by dirlist2 and the standard directories.
That is, if the compiler is called with any number of occurrences of -L, as in:
f95 ... -Lpath1 ... -Lpathn ...
then the search order is:
dirlist1 path1 ... pathn dirlist2 standard_paths
When the LD_LIBRARY_PATH variable contains only one colon-separated list of directories, it is interpreted as dirlist2.
In the Solaris operating environment, a similar environment variable, LD_LIBRARY_PATH_64 can be used to override LD_LIBRARY_PATH when searching for 64-bit dependencies. See the Solaris Linker and Libraries Guide and the ld(1) man page for details.
On a 32-bit SPARC processor, LD_LIBRARY_PATH_64 is ignored.
If only LD_LIBRARY_PATH is defined, it is used for both 32-bit and 64-bit linking.
If both LD_LIBRARY_PATH and LD_LIBRARY_PATH_64 are defined, 32-bit linking will be done using LD_LIBRARY_PATH, and 64-bit linking with LD_LIBRARY_PATH_64.
Use of the LD_LIBRARY_PATH environment variable with production software is strongly discouraged. Although useful as a temporary mechanism for influencing the runtime linker’s search path, any dynamic executable that can reference this environment variable will have its search paths altered. You might see unexpected results or a degradation in performance.
Use the -llibrary compiler option to name additional libraries for the linker to search when resolving external references. For example, the option -lmylib adds the library libmylib.so or libmylib.a to the search list.
The linker looks in the standard directory paths to find the additional libmylib library. The -L option (and the LD_LIBRARY_PATH environment variable) creates a list of paths that tell the linker where to look for libraries outside the standard paths.
Were libmylib.a in directory /home/proj/libs, then the option–L/home/proj/libs would tell the linker where to look when building the executable:
demo% f95 -o pgram part1.o part2.o -L/home/proj/libs -lmylib |
For any particular unresolved reference, libraries are searched only once, and only for symbols that are undefined at that point in the search. If you list more than one library on the command line, then the libraries are searched in the order in which they are found on the command line. Place -llibrary options as follows:
Place the -llibrary option after any .f, .for, .F, .f95, or .o files.
If you call functions in libx, and they reference functions in liby, then place -lx before -ly.
The -Ldir option adds the dir directory path to the library search list. The linker searches for libraries first in any directories specified by the -L options and then in the standard directories. This option is useful only if it is placed preceding the–llibrary options to which it applies.
With dynamic libraries, changing the library search path and order of loading differs from the static case. Actual linking takes place at runtime rather than build time.
When building the executable file, the linker records the paths to shared libraries in the executable itself. These search paths can be specified using the -Rpath option. This is in contrast to the -Ldir option which indicates at buildtime where to find the library specified by a -llibrary option, but does not record this path into the binary executable.
The directory paths that were built in when the executable was created can be viewed using the dump command.
Example: List the directory paths built into a.out:
demo% f95 program.f -R/home/proj/libs -L/home/proj/libs -lmylib demo% dump -Lv a.out | grep RPATH [5] RPATH /home/proj/libs:/opt/SUNWspro/lib |
At runtime, the linker determines where to find the dynamic libraries that an executable needs from:
The value of LD_LIBRARY_PATH at runtime
The paths that had been specified by -R at the time the executable file was built
As noted earlier, use of LD_LIBRARY_PATH can have unexpected side-effects and is not recommended.
When the dynamic linker cannot locate a needed library, it issues this error message:
ld.so: prog: fatal: libmylib.so: can’t open file: |
The message indicates that the libraries are not where they are supposed to be. Perhaps you specified paths to shared libraries when the executable was built, but the libraries have subsequently been moved. For example, you might have built a.out with your own dynamic libraries in /my/libs/, and then later moved the libraries to another directory.
Use ldd to determine where the executable expects to find the libraries:
demo% ldd a.out libfui.so.1 => /opt/SUNWspro/lib/libfui.so.1 libfai.so.1 => /opt/SUNWspro/lib/libfai.so.1 libfai2.so.1 => /opt/SUNWspro/lib/libfai2.so.1 libfsumai.so.1 => /opt/SUNWspro/lib/libfsumai.so.1 libfprodai.so.1 => /opt/SUNWspro/lib/libfprodai.so.1 libfminlai.so.1 => /opt/SUNWspro/lib/libfminlai.so.1 libfmaxlai.so.1 => /opt/SUNWspro/lib/libfmaxlai.so.1 libfminvai.so.1 => /opt/SUNWspro/lib/libfminvai.so.1 libfmaxvai.so.1 => /opt/SUNWspro/lib/libfmaxvai.so.1 libfsu.so.1 => /opt/SUNWspro/lib/libfsu.so.1 libsunmath.so.1 => /opt/SUNWspro/lib/libsunmath.so.1 libm.so.1 => /usr/lib/libm.so.1 libc.so.1 => /usr/lib/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1 |
If possible, move or copy the libraries into the proper directory or make a soft link to the directory (using ln -s) in the directory that the linker is searching. Or, it could be that LD_LIBRARY_PATH is not set correctly. Check that LD_LIBRARY_PATH includes the path to the needed libraries at runtime.