Library
Contents
Overview
If you are a programmer, you will want to re-use code written by others and design your program to be modular. You build up libraries containing re-usable code. Here is a library that contains functions for the KDE graphical user interface:
$ file /usr/lib64/libkdeui.so.5.0.0 /usr/lib64/libkdeui.so.5.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
There are two types of linking to libraries:
- static linking takes the code from the library and combines it with the main program's code into an executable
- dynamic linking forms an executable that loads the library code when it is executed.
Dynamic linking has the advantages:
- if you link against a software with a bug in the library, this bug can be fixed without the need to touch your executable.
- if more than one executable uses the same shared library, the overall memory consumption is lower
- the executable needs less disc space
Statically linked executables have the advantages:
- they do not depend on other libraries in the system that may not yet be installed. (important if you set up Linux from scratch).
- you can use them in another distribution that might have different libraries installed
- you can be sure how they will behave - less testing effort
"dynamically linked libraries" are also called "shared libraries" or "shared objects" on Linux. Their extension typically is .so (usually plus some version numbers). On MS Windows the extension is .dll, on Mac OS X, .dylib.
Find out dependencies
To find out which shared objects are required by an application, use ldd:
bash$ ldd /usr/X11R6/bin/glxgears libGL.so.1 => /usr/X11R6/lib/libGL.so.1 (0x4001a000) libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x40080000) libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x4008e000) libpthread.so.0 => /lib/libpthread.so.0 (0x40168000) libm.so.6 => /lib/libm.so.6 (0x4017c000) libc.so.6 => /lib/libc.so.6 (0x4019d000) libdl.so.2 => /lib/libdl.so.2 (0x402ba000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
ldd prints what libraries the object file will need for running, then the path info of the selected library file.
Now what happens when you execute a program:
- The dynamic linker ld.so checks for the needed shared libs.
- ld.so reads ld.so.cache and finds out the locations of the shared lib files.
- ld.so loads the libs into memory, and gives control to the program.
Creating your own libraries
This is an example how you get your own dynamic linked library and a program that uses it. The only thing you will need to is to install gcc:
cat > main.cpp << EOF #include <iostream> #include <dlfcn.h> extern "C" void help(); int main() { help(); return 0; } EOF
We have now created your main program. It contains a declaration of the function help(), but no implementation. The program does nothing more than to call the function help(), notably, without knowing about its implementation.
cat > help.cpp << EOF #include <iostream> extern "C" void help() { std::cout << "hello world" << '\n'; } EOF
We have now created your library. It implements the function help().
gcc help.cpp -o libhelp.so -ldl -shared -fPIC
We have now built your library, help.so
g++ main.cpp -lhelp
Now we have built an executable a.out that uses a library libhelp.so. This looks for me like this:
tweedleburg:~/test # ldd a.out linux-vdso.so.1 => (0x00007fff6dffe000) libhelp.so => not found libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fec65a02000) libm.so.6 => /lib64/libm.so.6 (0x00007fec657ac000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fec65595000) libc.so.6 => /lib64/libc.so.6 (0x00007fec6523c000) /lib64/ld-linux-x86-64.so.2 (0x00007fec65d0e000)
Of course we cannot get it running:
tweedleburg:~/test # ./a.out ./a.out: error while loading shared libraries: libhelp.so: cannot open shared object file: No such file or directory
Without the correct path to search the libraries:
tweedleburg:~/test # export LD_LIBRARY_PATH=. tweedleburg:~/test # ./a.out hello world
Static libraries
For a static library (or "archive"):
ar -r libFooBar.a foo.o bar.o gcc -o your_app main.o libFooBar.a