| Add comments here | |
|
|
| |
DLL stands for Dynamically Loadable Library. This chapter
follows directly from our construction of static (.a)
libraries in Chapter 25. Creating a DLL is not as
relevant as installing them. Here I will show you both so that you
have a good technical overview of how DLL's work on UNIX. You
can then promptly forget everything except ldconfig and
LD_LIBRARY_PATH discussed below.
|
| |
The .a library file is good for creating functions that
many programs can include. This is called code reuse. But note
how the .a file is linked into (included) in the executable
test above. test is enlarged by the size of
libsimple_math.a. Where there are hundreds of programs that
use the same .a file, that code is effectively duplicated all
over the file-system. Such inefficiency was deemed unacceptable
since long before LINUX, so library files were invented that only link
with the program when it runs -- a process known as
dynamic linking. Instead of .a files, similar .so
(shared object) files live in /lib/
and /usr/lib/ that get automatically linked to a program when it
runs.
|
| |
|
| |
|
| |
To create a DLL requires several changes to the Makefile
on page :
|
| |
5
10
15
20
|
OBJS = simple_math_sqrt.o simple_math_pow.o
LIBNAME = simple_math
SONAME = libsimple_math.so.1.0.0
SOVERSION = libsimple_math.so.1.0
CFLAGS = -Wall
all: lib$(LIBNAME).so test
test: lib$(LIBNAME).so test.o
gcc $(CFLAGS) -o $@ test.o -L. -l${LIBNAME}
lib$(LIBNAME).so: $(OBJS)
gcc -shared $(CFLAGS) $(OBJS) -lc -Wl,-soname -Wl,$(SOVERSION) \
-o $(SONAME) && \
ln -sf $(SONAME) $(SOVERSION) && \
ln -sf $(SONAME) lib$(LIBNAME).so
.c.o:
gcc -fPIC -DPIC $(CFLAGS) -c -o $*.o $<
clean:
rm -f *.o *.a *.so test
|
|
| |
The -shared option to gcc builds our shared
library. The -W options are linker options that set the version
number of the library that linking programs will load at run time. The
-fPIC -DPIC means to generate position-independent code,
i.e. code suitable for dynamic linking. After running make we have,
|
lrwxrwxrwx 1 root root 23 Sep 17 22:02 libsimple_math.so -> libsimple_math.so.1.0.0
lrwxrwxrwx 1 root root 23 Sep 17 22:02 libsimple_math.so.1.0 -> libsimple_math.so.1.0.0
-rwxr-xr-x 1 root root 6046 Sep 17 22:02 libsimple_math.so.1.0.0
-rwxr-xr-x 1 root root 13677 Sep 17 22:02 test
|
|
| |
|
| |
You may observe that our three .so files are
similar to the many in /lib/ and /usr/lib/. This
complicated system of linking and symlinking is part of the process
of library versioning. Although generating a DLL is out of the
scope of most system admin's tasks, library version is important to
understand:
|
| |
DLL's have a problem. Consider a DLL that is outdated or buggy:
simply copying the DLL over with a new one will effect all the
applications that use it. If these applications rely on certain
behaviour of the DLL code, then they will probably crash with the
fresh DLL. UNIX has elegantly solved this problem by allowing
multiple versions of DLL's to be present simultaneously. The
programs themselves have their required version number built into
them. Try,
which will show the DLL files that test is scheduled to link
with:
|
libsimple_math.so.1.0 => ./libsimple_math.so.1.0 (0x40018000)
libc.so.6 => /lib/libc.so.6 (0x40022000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
|
At the moment we are interested in libsimple_math.so.1.0.
Note how it matches the SOVERSION variable in the
Makefile. Note also how we have chosen our symlinks.
We are effectively allowing test to link with any future
libsimple_math.so.1.0.? (were our simple_math library
to be upgraded to a new version) purely because of the way we have chosen
our symlinks. However, it will not link with any
library libsimple_math.so.1.1.? for example. As developers of
libsimple_math, we are deciding that libraries of a different
minor26.1version number will be incompatible, while libraries of a different
patch level will not be incompatible.
|
| |
We could also change SOVERSION to
libsimple_math.so.1. This would effectively be saying that
future libraries of different minor version number are compatible; only
a change in the major version number would dictate incompatibility.
|
| |
|
| |
If we try to run ./test you will be greeted with an error
while loading shared libraries message. This is because the
dynamic linker does not search the current directory for .so
files. To run your program, you will have to install your library:
|
mkdir -p /usr/local/lib
install -m 0755 libsimple_math.so libsimple_math.so.1.0 \
libsimple_math.so.1.0.0 /usr/local/lib
|
Then edit the /etc/ld.so.conf file and add a line
Then reconfigure your libraries with
Finally, run your program with
|
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib"
./test
|
|
| |
ldconfig configures all libraries on the system.
It recreates appropriate symlinks (as we did) and rebuilds a lookup
cache. The library directories it considers are /lib,
/usr/lib and those listed in /etc/ld.so.config.
The ldconfig command should be run automatically when the
system boots and manually whenever libraries are installed or upgraded.
|
| |
The LD_LIBRARY_PATH environment variable is
relevant to every executable on the system, and similar to the
PATH environment variable. LD_LIBRARY_PATH
dictates what directories should be searched when looking for
library files. Here, we appended /usr/local/lib to the
search path in case it was missing. Note that even with
LD_LIBRARY_PATH unset, /lib and /usr/lib
will always be searched.
|