Difference between revisions of "Library"

From Linuxintro
imported>ThorstenStaerk
imported>ThorstenStaerk
 
(3 intermediate revisions by the same user not shown)
Line 41: Line 41:
  
 
== Shared libraries ==
 
== Shared 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]]:
+
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
 
  [[cat]] > main.cpp << EOF
 
  #include <iostream>
 
  #include <iostream>
Line 60: Line 60:
 
  extern "C" void help()  
 
  extern "C" void help()  
 
  {
 
  {
   std::cout << "hello world" << '\
+
   std::cout << "hello world" << '\n';
';
 
 
  }
 
  }
 
  EOF
 
  EOF
Line 87: Line 86:
 
== Static libraries ==
 
== Static libraries ==
 
For a static library (or "archive"):
 
For a static library (or "archive"):
  [[ar]] -r libFooBar.a foo.o bar.o
+
  [http://unixhelp.ed.ac.uk/CGI/man-cgi?ar ar] -r libFooBar.a foo.o bar.o
 
  gcc -o your_app main.o libFooBar.a
 
  gcc -o your_app main.o libFooBar.a
  

Latest revision as of 14:22, 20 April 2014

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.

Shared Libraries

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.

Loading shared libs at runtime

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

Shared 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

See also