When an executable is run that relies on shared libraries not defined in the global search path, an error similar to the following is displayed:
$ curl ld.so.1: curl: fatal: libgcc_s.so.1: open failed: No such file or directory Killed
Typically this problem is fixed by running ldd(1) on the executable, locating the missing shared libraries, and adding one or more directories to the LD_LIBRARY_PATH environment variable:
$ ldd curl libcurl.so.3 => /tmp/curl1/lib/libcurl.so.3 libdl.so.1 => /usr/lib/libdl.so.1 libsocket.so.1 => /usr/lib/libsocket.so.1 libnsl.so.1 => /usr/lib/libnsl.so.1 libz.so.1 => /usr/lib/libz.so.1 libc.so.1 => /usr/lib/libc.so.1 libgcc_s.so.1 => (file not found) libmp.so.2 => /usr/lib/libmp.so.2 /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1 $ export LD_LIBRARY_PATH=/usr/local/lib $ curl curl: try 'curl --help' or 'curl --manual' for more information
Using LD_LIBRARY_PATH for this purpose is a complete hack, and according to the linker gurus, this variable should be avoided. This is easy to do, since the vast majority of executable formats allow a runtime search path to be added to the executable. For Solaris ELF executables, the native linker's "-R" (record path) option can be used to record a runtime search path:
$ export LDFLAGS="-R/usr/local/lib" $ ./configure --prefix=/tmp/curl2 $ make $ make install
To view the runtime search path in a Solaris ELF executable, the dump utility can be run with the "-L" (dump dynamic linking information) and "-v" (print verbose information) options, and an executable to query:
$ dump -Lv curl | egrep '(RPATH|RUNPATH)' [9] RUNPATH /usr/local/lib [10] RPATH /usr/local/lib $ curl curl: try 'curl --help' or 'curl --manual' for more information
If a binary is already built, the setrpath utility can often be used to update the search path in an ELF executable:
$ curl ld.so.1: curl: fatal: libgcc_s.so.1: open failed: No such file or directory Killed $ gcc -o setrpath setrpath.c -lelf $ setrpath curl "/usr/local/lib" Old RPATH: /tmp/curl1/lib:/tmp/curl:/tmp:/curl:/tmp/curl:/tmp/curl New RPATH set to: /usr/local/lib $ setrpath libcurl.so.3.0.0 "/usr/local/lib" Old RPATH: /tmp/curl:/tmp:/curl:/tmp/curl:/tmp/curl New RPATH set to: /usr/local/lib $ curl curl: try 'curl --help' or 'curl --manual' for more information
To use setrpath, you need to ensure that enough space exists to accomodate the new seach path. For binaries that need to move within a file system, the Solaris $ORIGIN variable should be used instead of absolute paths. If you haven't already, I highly recommend sitting down with the Solaris linkers and libraries guide. This document contains an awesome introduction to the Solaris linker, and provides a detailed overview of the dynamic linking process. If you have questions or comments on the article, please feel free to E-mailthe author.
The following references were used while writing this article: