In addition to checking for software
package dependencies, you may also need to verify that your system is
configured properly to access the libraries an application needs to run. In
this part of the chapter, you will learn how to do this. The following topics
are addressed:
• How shared libraries work
• Managing shared library dependencies
Let’s begin by discussing how shared
libraries work.
How Shared Libraries Work
On Linux, applications running on
the system can share code elements called shared libraries.
This is very useful. Shared libraries make it
such that software developers don’t have to reinvent the wheel each time they
write a new program.
If you think about it, many
functions are commonly used across many programs. For example, the process for
opening a file, saving a file, and closing an open file are the same no matter
what application is being used. Without shared libraries, programmers would
have to include the code for completing these basic tasks in each application
they write. What a waste of time and resources!
Instead, with shared libraries,
software developers can focus on the code elements that are unique to the
individual application.
For common elements that are shared
across applications, they can simply link to the prewritten code in a shared
library and not worry about rewriting the code.
Using shared libraries has many
benefits. Obviously, it dramatically speeds up development time. It also makes
the programs being written smaller and leaner.
There are two types of shared libraries on Linux:
• Dynamic
Dynamic shared libraries exist as
files in the Linux file system. Programmers simply insert links to the
functions in these shared libraries in their program code. The functions are
called from the dynamic shared libraries when the program is run, not integrated
into the program itself. A configuration file on the system contains a list of installed
dynamic shared libraries and where they are located in the file system. Using dynamic
shared libraries decreases the overall size of the executable after it’s
compiled.
However, they do create a dependency
issue. If the program calls a function from a dynamic shared library that isn’t
installed on the system (or has become unavailable for some reason), the
application will malfunction.
• Static
In contrast to dynamic shared
libraries, static shared libraries are linked statically into the program when
it’s compiled. In essence, with static libraries, the actual code elements for
the functions called are integrated directly into the application itself.
Obviously, this results in larger
applications. However, it has the advantage of making the application
independent of having the shared libraries installed on the system where it is running,
as is the case with dynamic libraries.
Which type is best? It depends on
the application. Most applications you will use on a day-to-day basis use
dynamic shared libraries. This allows them to provide a lot of functionality
with a relatively small footprint on the hard drive.
However, there are many applications
that use static libraries, especially applications that are designed to help
you rescue a malfunctioning system. Instead of linking to dynamic shared
libraries (which may not be available in a system rescue scenario), these applications
are completely self-contained and can run in a minimal Linux environment.
Shared library files use a special
naming format to help you identify the type of shared library it is. This
syntax is as follows:
libname.type.version
Notice that the filename of all shared
libraries starts with lib.
It is followed by the name of the shared
library. The type part of the filename identifies the type of shared library.
The characters “so” here indicate the
file is a dynamic shared library, whereas “a” indicates the file is a static library. The version part of the
filename specifies the version number of the library. For example, libfreetype.so.6.4.0
is a dynamic shared library.
With this in mind, let’s discuss how
you manage shared library dependencies.
Managing Shared Library Dependencies
As noted earlier, Linux uses a
configuration file to tell applications running on the system where they can
find the dynamic shared library files on the system. Using this type of
configuration provides application developers with a degree of independence.
They don’t have to worry about where the shared libraries will reside when
their programs are run. They let the configuration file tell the program where
they are, wherever that happens to be on a particular Linux system.
The dynamic shared library
configuration file is /etc/ld.so.conf.
Here is a sample file:
openSUSE:/etc # cat ld.so.conf
/usr/X11R6/lib64/Xaw3d
/usr/X11R6/lib64
/usr/lib64/Xaw3d
/usr/X11R6/lib/Xaw3d
/usr/X11R6/lib
/usr/lib/Xaw3d
/usr/x86_64-suse-linux/lib
/usr/local/lib
/opt/kde3/lib
/lib64
/lib
/usr/lib64
/usr/lib
/usr/local/lib64
/opt/kde3/lib64
include /etc/ld.so.conf.d/*.conf
As you can see in this example, the
file simply contains a list of paths in the file system where shared library
files are stored. Applications that are linked to functions in these files can
search through these paths to locate the appropriate libraries.
The /lib/ and /usr/lib/ directories are always assumed to contain shared libraries, so they aren’t listed in the /etc/ld.so.conf
file.
To view a list of all shared
libraries available on your Linux system, enter ldconfig –p
at the shell prompt. Here is an
example:
openSUSE:~ # ldconfig –p
1423 libs found in cache
'/etc/ld.so.cache'
libzypp.so.706 (libc6,x86-64) => /usr/lib64/libzypp.so.706
libzio.so.0 (libc6,x86-64) => /usr/lib64/libzio.so.0
libz.so.1 (libc6,x86-64) => /lib64/libz.so.1
libz.so.1 (libc6) => /lib/libz.so.1
libz.so (libc6,x86-64) => /usr/lib64/libz.so
liby2util.so.4 (libc6,x86-64) => /usr/lib64/liby2util.so.4
liby2.so.2 (libc6,x86-64) => /usr/lib64/liby2.so.2
libyui.so.3 (libc6,x86-64) => /usr/lib64/libyui.so.3
libycpvalues.so.3 (libc6,x86-64) => /usr/lib64/libycpvalues.so.3
You can also view the shared
libraries required by a specific application using the ldd command. The syntax is
Ldd –v executable_filename
For example, if you wanted to see
what shared libraries are required by the ip command (which is used to manage
network connections), you would enter
ldd –v /sbin/ip
at the shell prompt.
An example is shown next:
openSUSE:~ # ldd -v /sbin/ip
linux-vdso.so.1 =>
(0x00007fffe4ab2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f7c07e7d000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7c07b1d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7c08081000)
Version information:
/sbin/ip:
libdl.so.2 (GLIBC_2.2.5) =>
/lib64/libdl.so.2
libc.so.6 (GLIBC_2.7) =>
/lib64/libc.so.6
libc.so.6 (GLIBC_2.4) =>
/lib64/libc.so.6
One of the key uses for the ldd command is to check for shared library
dependencies. It determines whether
all of the libraries required by the application in question have been
installed. If they have, you won’t see any error messages, as shown in the
preceding example.
If a library file is missing, an
error message will be displayed. You can then locate and install the missing
library and all will be well with the world.
So, how does an application know
which directories to look in when trying to locate a shared library? The applications don’t actually check the
/etc/ld.so.conf conf file. Instead, they
check the library cache and the LD_LIBRARY_PATH environment
variable.
The library cache is /etc/ld.so.cache. This file contains a list of all the system libraries and
is refreshed when the system is initially booted.
This is key. If you add a new
dynamic library directory to the /etc/ld.so.conf file, you’ll be very frustrated
when you try to run the applications that are linked to the libraries in this
directory.
That’s because the library cache hasn’t been updated with
the new information. To fix this, you have two options:
OPTIONS To UPDATE SHARED LIBRARIES:
A: Use ldconfig
. The ldconfig command is used to rebuild the library cache manually.
B: Set LD_LIBRARY_PATH
. You can also add the path to the
LD_LIBRARY_PATH environment variable. You probably want to add the new path to
the end of the list of directories that may already exist in the variable, so
you should use the following commands:
Set
LD_LIBRARY_PATH=$LD_LIBRARY_PATH; new_path
export
LD_LIBRARY_PATH
Generally speaking, the first option is the preferred one. This ensures the shared libraries are always available to
the applications that need them, even if the system is rebooted.
I usually set the value of LD_LIBRARY_PATH only in
situations where I have two versions of the same shared library installed in
different directories and I want to use one version over the other.
Exercise 8-6: Working with Shared
Libraries
In this exercise, you will practice
managing shared libraries. You can perform this exercise using the virtual
machine that comes with this book. Run snapshot 8-3 for the correctly
configured environment.
Complete the following:
1. With your system running, open a
terminal session.
2. If necessary, change to your root
user account by entering
su – followed by your root user’s
password.
3.
View the shared libraries used by
the ping executable on your system by entering ldd –v /bin/ping at the shell prompt. You should see that ping
requires the libc.so.6 shared library.
4. Find the location of the
lib64/libc.so.6 library file on your system by entering find / –name libc.so.6 at the shell prompt. On a 32-bit system, you
should see that the file resides in /lib. On a 64-bit system, it probably
resides in /lib64.
5. View your system’s library cache
by entering ldconfig –p at the shell
prompt.
6. Rebuild your library cache by
entering ldconfig –v at the shell
prompt
No comments:
Post a Comment