C/C++ dynamic library

Sometimes ago October 2005, I was playing with C/C++ just to refresh what school taught me. And as a FSF fan I was using the gcc compiler (via command line). So after the very first very easy attempts I stumbled in the dynamic library.

Dynamic (or shared) library are those part of code that isn’t included in the binary executable. In compiling time, the linker verify the program’s required symbols and bind them with the shared library. During the execution time, the dynamic loader, check which libraries are required by the program, load them into memory (if they weren’t already) and then “attach” the copy of the executed program.

This dinamyc load slow down a bit the application startup, but you’ll get the advantages of getting a lighter binary, use less RAM resources (many programs access the same shared library), and in case of error in the library, fix them and recompile the library will solve the error in all applications who’s using it.

An example of shared library in Linux is the libc.

In order to compile a shared library, you need to compile it for Position Independent Code (PIC). This because when you create the library, you wont know in which position of memory the library will be inserted for the program who’s using it, so all callings have to be done in relative way, not absolute. The g++ option to obtain this code is -fpic.

When compiling a shared library, you’ll need to compile them for different architectures, to obtain this the g++ option to use is -shared.

So let’s say we have mickey.cc and mouse.cc files and we want to create the miceland library, the command to use is something similar to

g++ -Wall -fpic -c mickey.cc
g++ -Wall -fpic -c mouse.cc
g++ -shared -o libmiceland.so mickey.o mouse.o

notice that the library file name begin with lib and and with so extension.

In order to link the program to the shared library, and assuming we have the library in the current directory (same of the program), the command to use is

g++ -o shared-run shared-run.cc -L. -lmiceland

If you try to execute the binary you could get into the same error


$ ./shared-run
./shared-run: error while loading shared libraries: libmiceland.so: cannot open shared object file: No such file or directory

This is because the loader cannot find the library. It isn’t in a standard directory. Once again ldd comes in our help

$ ldd shared-run
libmiceland.so => not found
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40021000)
libm.so.6 => /lib/tls/libm.so.6 (0x400dc000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x400fe000)
libc.so.6 => /lib/tls/libc.so.6 (0x40107000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

In order to solve this problem, it is possible to set the LD_LIBRARY_PATH environment variable

$ export LD_LIBRARY_PATH=/dir/with/library:$LD_LIBRARY_PATH
$ echo $LD_LIBRARY_PATH
/dir/with/library:
$ ldd shared-run
libmiceland.so => /dir/with/library/libmiceland.so (0x40018000)
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40024000)
libm.so.6 => /lib/tls/libm.so.6 (0x400de000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40100000)
libc.so.6 => /lib/tls/libc.so.6 (0x40109000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

If we need it, it’s possible to set this new directory (were the library actually reside) as a system’s directory for libraries: just add it to the /etc/ld.so.conf file and then use the ldconfig program (all as root).

It is also possible in compilation time to tell to the program where to find the library. This is achieved with the -rpath flag:

g++ -Wall -o shared-run shared-run.cc -Wl,-rpath,/dir/with/library/ -L. -lmiceland

The priorities with witch the dynamic loader search for the library are -rpath, LD_LIBRARY_PATH, /etc/ld.so.conf

If in the same directory there’s a static and a dynamic library with the same name, the loader will prefer the last one. You can tell it to prefer the static one if you compile with the -static option.

Advertisements

4 thoughts on “C/C++ dynamic library

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s