Linux package shared libraries

Understanding Shared Libraries in Linux

In programming, a library is an assortment of pre-compiled pieces of code that can be reused in a program. Libraries simplify life for programmers, in that they provide reusable functions, routines, classes, data structures, and so on (written by another programmer), which they can use in their programs.

For instance, if you are building an application that needs to perform math operations, you don’t have to create a new math function for that, you can simply use existing functions in libraries for that programming language.

Examples of libraries in Linux include libc (the standard C library) or Glibc (GNU version of the standard C library), libcurl (multiprotocol file transfer library), libcrypt (library used for encryption, hashing, and encoding in C), and many more.

Linux supports two classes of libraries, namely:

  • Static libraries – are bound to a program statically at compile time.
  • Dynamic or shared libraries – are loaded when a program is launched and loaded into memory and binding occurs at run time.

Dynamic or shared libraries can further be categorized into:

  • Dynamically linked libraries – here a program is linked with the shared library and the kernel loads the library (in case it’s not in memory) upon execution.
  • Dynamically loaded libraries – the program takes full control by calling functions with the library.

Shared Library Naming Conventions

Shared libraries are named in two ways: the library name (a.k.a soname) and a “filename” (absolute path to file which stores library code).

For example, the soname for libc is libc.so.6: where lib is the prefix, c is a descriptive name, so means shared object, and 6 is the version. And its filename is: /lib64/libc.so.6. Note that the soname is actually a symbolic link to the filename.

Locating Shared Libraries in Linux

Shared libraries are loaded by ld.so (or ld.so.x) and ld-linux.so (or ld-linux.so.x) programs, where x is the version. In Linux, /lib/ld-linux.so.x searches and loads all shared libraries used by a program.

A program can call a library using its library name or filename, and a library path stores directories where libraries can be found in the filesystem. By default, libraries are located in /usr/local/lib, /usr/local/lib64, /usr/lib and /usr/lib64; system startup libraries are in /lib and /lib64. Programmers can, however, install libraries in custom locations.

The library path can be defined in /etc/ld.so.conf file which you can edit with a command-line editor.

The line(s) in this file instruct the kernel to load file in /etc/ld.so.conf.d. This way, package maintainers or programmers can add their custom library directories to the search list.

If you look into the /etc/ld.so.conf.d directory, you’ll see .conf files for some common packages (kernel, mysql, and postgresql in this case):

# ls /etc/ld.so.conf.d kernel-2.6.32-358.18.1.el6.x86_64.conf kernel-2.6.32-696.1.1.el6.x86_64.conf mariadb-x86_64.conf kernel-2.6.32-642.6.2.el6.x86_64.conf kernel-2.6.32-696.6.3.el6.x86_64.conf postgresql-pgdg-libs.conf

If you take a look at the mariadb-x86_64.conf, you will see an absolute path to package libraries.

# cat mariadb-x86_64.conf /usr/lib64/mysql

The method above sets the library path permanently. To set it temporarily, use the LD_LIBRARY_PATH environment variable on the command line. If you want to keep the changes permanent, then add this line in the shell initialization file /etc/profile (global) or ~/.profile (user-specific).

# export LD_LIBRARY_PATH=/path/to/library/file

Managing Shared Libraries in Linux

Let us now look at how to deal with shared libraries. To get a list of all shared library dependencies for a binary file, you can use the ldd utility. The output of ldd is in the form:

library name => filename (some hexadecimal value) OR filename (some hexadecimal value) #this is shown when library name can’t be read

This command shows all shared library dependencies for the ls command.

# ldd /usr/bin/ls OR # ldd /bin/ls
Sample Output
linux-vdso.so.1 => (0x00007ffebf9c2000) libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003b71e00000) librt.so.1 => /lib64/librt.so.1 (0x0000003b71600000) libcap.so.2 => /lib64/libcap.so.2 (0x0000003b76a00000) libacl.so.1 => /lib64/libacl.so.1 (0x0000003b75e00000) libc.so.6 => /lib64/libc.so.6 (0x0000003b70600000) libdl.so.2 => /lib64/libdl.so.2 (0x0000003b70a00000) /lib64/ld-linux-x86-64.so.2 (0x0000561abfc09000) libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003b70e00000) libattr.so.1 => /lib64/libattr.so.1 (0x0000003b75600000)

Because shared libraries can exist in many different directories, searching through all of these directories when a program is launched would be greatly inefficient: which is one of the likely disadvantages of dynamic libraries. Therefore a mechanism of caching is employed, performed by the program ldconfig.

Читайте также:  Scanning disk in linux

By default, ldconfig reads the content of /etc/ld.so.conf, creates the appropriate symbolic links in the dynamic link directories, and then writes a cache to /etc/ld.so.cache which is then easily used by other programs.

This is very important especially when you have just installed new shared libraries or created your own, or created new library directories. You need to run the ldconfig command to effect the changes.

# ldconfig OR # ldconfig -v #shows files and directories it works with

After creating your shared library, you need to install it. You can either move it into any of the standard directories mentioned above and run the ldconfig command.

Alternatively, run the following command to create symbolic links from the soname to the filename:

# ldconfig -n /path/to/your/shared/libraries

To get started with creating your own libraries, check out this guide from The Linux Documentation Project(TLDP).

That’s all for now! In this article, we gave you an introduction to libraries and explained shared libraries, and how to manage them in Linux. If you have any queries or additional ideas to share, use the comment form below.

Источник

8. Shared Libraries¶

Shared libraries are compiled code which is intended to be shared among several different programs. They are distributed as .so files in /usr/lib/ .

A library exports symbols which are the compiled versions of functions, classes and variables. A library has a name called an SONAME which includes a version number. This SONAME version does not necessarily match the public release version number. A program gets compiled against a given SONAME version of the library. If any of the symbols is removed or changes then the version number needs to be changed which forces any packages using that library to be recompiled against the new version. Version numbers are usually set by upstream and we follow them in our binary package names called an ABI number, but sometimes upstreams do not use sensible version numbers and packagers have to keep separate version numbers.

Читайте также:  Linux свободно на разделе

Libraries are usually distributed by upstream as standalone releases. Sometimes they are distributed as part of a program. In this case they can be included in the binary package along with the program (this is called bundling) if you do not expect any other programs to use the library, more often they should be split out into separate binary packages.

The libraries themselves are put into a binary package named libfoo1 where foo is the name of the library and 1 is the version from the SONAME. Development files from the package, such as header files, needed to compile programs against the library are put into a package called libfoo-dev .

8.1. An Example¶

We will use libnova as an example:

$ bzr branch ubuntu:trusty/libnova $ sudo apt-get install libnova-dev

To find the SONAME of the library run:

$ readelf -a /usr/lib/libnova-0.12.so.2 | grep SONAME

The SONAME is libnova-0.12.so.2 , which matches the file name (usually the case but not always). Here upstream has put the upstream version number as part of the SONAME and given it an ABI version of 2 . Library package names should follow the SONAME of the library they contain. The library binary package is called libnova-0.12-2 where libnova-0.12 is the name of the library and 2 is our ABI number.

If upstream makes incompatible changes to their library they will have to reversion their SONAME and we will have to rename our library. Any other packages using our library package will need to recompiled against the new version, this is called a transition and can take some effort. Hopefully our ABI number will continue to match upstream’s SONAME but sometimes they introduce incompatibilities without changing their version number and we will need to change ours.

Looking in debian/libnova-0.12-2.install we see it includes two files:

usr/lib/libnova-0.12.so.2 usr/lib/libnova-0.12.so.2.0.0

The last one is the actual library, complete with minor and point version number. The first one is a symlink which points to the actual library. The symlink is what programs using the library will look for, the running programs do not care about the minor version number.

libnova-dev.install includes all the files needed to compile a program with this library. Header files, a config binary, the .la libtool file and libnova.so which is another symlink pointing at the library, programs compiling against the library do not care about the major version number (although the binary they compile into will).

Читайте также:  Linux логи командной строки

.la libtool files are needed on some non-Linux systems with poor library support but usually cause more problems than they solve on Debian systems. It is a current Debian goal to remove .la files and we should help with this.

8.2. Static Libraries¶

The -dev package also ships usr/lib/libnova.a . This is a static library, an alternative to the shared library. Any program compiled against the static library will include the code directory into itself. This gets round worrying about binary compatibility of the library. However it also means that any bugs, including security issues, will not be updated along with the library until the program is recompiled. For this reason programs using static libraries are discouraged.

8.3. Symbol Files¶

When a package builds against a library the shlibs mechanism will add a package dependency on that library. This is why most programs will have Depends: $ in debian/control . That gets replaced with the library dependencies at build time. However shlibs can only make it depend on the major ABI version number, 2 in our libnova example, so if new symbols get added in libnova 2.1 a program using these symbols could still be installed against libnova ABI 2.0 which would then crash.

To make the library dependencies more precise we keep .symbols files that list all the symbols in a library and the version they appeared in.

libnova has no symbols file so we can create one. Start by compiling the package:

The -nc will cause it to finish at the end of compilation without removing the built files. Change to the build and run dpkg-gensymbols for the library package:

$ cd ../build-area/libnova-0.12.2/ $ dpkg-gensymbols -plibnova-0.12-2 > symbols.diff

This makes a diff file which you can self apply:

Which will create a file named similar to dpkg-gensymbolsnY_WWI that lists all the symbols. It also lists the current package version. We can remove the packaging version from that listed in the symbols file because new symbols are not generally added by new packaging versions, but by the upstream developers:

$ sed -i s,-0ubuntu2,, dpkg-gensymbolsnY_WWI

Now move the file into its location, commit and do a test build:

$ mv dpkg-gensymbolsnY_WWI ../../libnova/debian/libnova-0.12-2.symbols $ cd ../../libnova $ bzr add debian/libnova-0.12-2.symbols $ bzr commit -m "add symbols file" $ bzr builddeb

If it successfully compiles the symbols file is correct. With the next upstream version of libnova you would run dpkg-gensymbols again and it will give a diff to update the symbols file.

8.4. C++ Library Symbols Files¶

C++ has even more exacting standards of binary compatibility than C. The Debian Qt/KDE Team maintain some scripts to handle this, see their Working with symbols files page for how to use them.

8.5. Further Reading¶

Junichi Uekawa’s Debian Library Packaging Guide goes into this topic in more detail.

Источник

Оцените статью
Adblock
detector