This note is referred from
http://rute.2038bug.com/node26.html.gz
Creating a DLL requires several changes to the
Makefile
on page
![[*]](https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_tc4DTD2qSmlM_mRTLayiX0ZePSK1GXnE-bqrtHe3jujl2P3F8ZMbI1TOjEL3MRs6GdYSIbGTBTv2hPbS2qT7JOkR-3EZy35w=s0-d)
:
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 mytest
mytest: lib$(LIBNAME).so mytest.o
gcc $(CFLAGS) -o $@ mytest.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 mytest
|
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 runtime. The
-fPIC -DPIC means to generate
position-independent code,
that is, 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 mytest
|
You may observe that our three
.so files are
similar to the many files 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 tasks, library versioning is important to
understand.
DLLs have a problem. Consider a DLL that is outdated or buggy:
simply overwriting the DLL file with an updated file will affect all the
applications that use it. If these applications rely on certain
behavior of the DLL code, then they will probably crash with the
fresh DLL. U
NIX has elegantly solved this problem by allowing
multiple versions of DLLs to be present simultaneously. The
programs themselves have their required version number built into
them. Try
which will show the DLL files that
mytest 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
mytest 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
minor [For this example we are considering libraries to be
named
libname
.so.major
.minor
.patch]version number will be incompatible, whereas 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 numbers are compatible; only
a change in the major version number would dictate incompatibility.
If you run
./mytest, you will be greeted with an
error
while loading shared libraries message. The reason is that 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"
./mytest
|
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 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.
No comments:
Post a Comment