Linux dynamic library version

What C library version does my system use?

Why not try it and see. I don’t know if the version tells you everything; what about patches? Or are distrubutions careful about altering the ABI? Isn’t the issue whether the exported symbols are resolved, or something like that?

Nice answers, but no one addresses how to do this on a Mac, where there is no ldd . I’m not sure if otool —version can be regarded as giving the same information.

@dubiousjim Someone could; just not me, because I’m not a Mac user. Around here you might have to ask specifically about that — part of the issue is perhaps people generally don’t use plain C much on OSX? But I’m sure there will be a regular who knows. You could also post a link to this in chat and see what happens, but probably a new, more specific question would be better.

6 Answers 6

GNU/Linux systems usually use either glibc (Fedora/Redhat family, Arch) or its close cousin, eglibc (Debian/Ubuntu family); since eglibc is now being merged back into glibc (see EGLIBC 2.19 Branch Created under «News»), in the near future they will all be glibc again.

The easiest way to check the exact version is to ask ldd , which ships with the C library.

> ldd --version ldd (GNU libc) 2.18 

On Raspbian (Debian 7 port for ARMv6 Broadcom SoC):

> ldd --version ldd (Debian EGLIBC 2.13-38+rpi2) 2.13 

If for whatever reason you have mixed and matched some parts or otherwise aren’t sure about ldd , you can query the C library directly.

> whereis libc.so libc: /usr/lib64/libc.a /usr/lib64/libc.so /usr/share/man/man7/libc.7.gz 

None of those is executable but they provide a clue about where to find one.

> $(find /usr/lib64/ -executable -name "*libc.so*") --version GNU C Library (GNU libc) stable release version 2.18, by Roland McGrath et al. 

However, it is not necessarily so easy, because the C library does not have to reside somewhere whereis can find it.

> whereis libc.so libc: /usr/share/man/man7/libc.7.gz 

Unfortunately, the man page does not provide a version number. ldd still comes in handy, since any working, dynamically linked executable on the system (e.g., almost everything in /usr/bin ) will link to the C library.

> ldd /usr/bin/touch /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6eed000) librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0xb6ed0000) libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6da1000) /lib/ld-linux-armhf.so.3 (0xb6efb000) libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6d82000) 

libc.so.6 is on the third line.

> /lib/arm-linux-gnueabihf/libc.so.6 --version GNU C Library (Debian EGLIBC 2.13-38+rpi2) stable release version 2.13, by Roland McGrath et al. 

@ElliottFrisch It was intended to apply to GNU/Linux, as in, «normal GNU/Linux» (adjective, noun), since there could be (are, I’m sure) systems which do not use (e)glibc but do use the rest of the GNU stack (bash, binutils, etc.). I would consider those «unusual» GNU/Linux systems. But I’ve removed the «normal » and changed it to «GNU/Linux systems usually use. «. Note I intentionally left the question open WRT OS specifics (there is no linux or GNU or glibc tag), so if you want to add an answer regarding any system appropriate to U&L, please do.

Читайте также:  Информация об оперативной системе linux

After I found it like you showed and I queried the version, it also printed available extensions! (in my case stubs, crypt, libidn, native threads and bind) and referred to ABI: libc ABIs: UNIQUE IFUNC.

Debian uses /lib/`uname -m`* path. So portable way would be: find /lib/`uname -m`* /usr/lib* -executable -name «*libc.so*» | xargs —version . Thanks for nice explanation.

A system isn’t actually limited to one C library. Most, though, primarily use only one, which will also be the one the default compiler uses. And since you’re downloading source code to compile, that’s the one you’re concerned with.

Start with a trivial program:

compile it using the compiler you’re going to use for the source code, then use ldd to find out where the C library is:

$ ldd ./libc-test linux-vdso.so.1 (0x00007fff2e5fe000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c8ad98000) /lib64/ld-linux-x86-64.so.2 (0x00007f8c8b171000) 

You now have the path to the C library. You could look this up in your package manager to find the package (e.g., dpkg -S /lib/x86_64-linux-gnu/libc.so.6 or rpm -q -f /lib/x86_64-linux-gnu/libc.so.6 ).

At least in the case of eglibc/glibc, you can run it:

$ /lib/x86_64-linux-gnu/libc.so.6 GNU C Library (Debian EGLIBC 2.18-4) stable release version 2.18, by Roland McGrath et al. Copyright (C) 2013 Free Software Foundation, Inc. ⋮ 

Finally, you could see if you can get clues from objdump -p /lib/x86_64-linux-gnu/libc.so.6 , by looking in the version definitions section:

Version definitions: 1 0x01 0x0865f4e6 libc.so.6 2 0x00 0x09691a75 GLIBC_2.2.5 3 0x00 0x09691a76 GLIBC_2.2.6 ⋮ 21 0x00 0x06969197 GLIBC_2.17 GLIBC_2.16 22 0x00 0x06969198 GLIBC_2.18 GLIBC_2.17 23 0x00 0x0963cf85 GLIBC_PRIVATE GLIBC_2.18 

Note how the GLIBC_2.18 symbol has the most recent version number among the symbols listed, and the library version is indeed 2.18. It’s eglibc, though (it aims to be binary-compatible with glibc 2.18, so it uses the same symbol versions).

You could also attempt to use strings to find out something about it. You’ll want to specify a longer minimal length ( -n ), or use grep to search for something:

$ strings /lib/x86_64-linux-gnu/libc.so.6 | grep 'version 5' $ strings /lib/x86_64-linux-gnu/libc.so.6 | grep -iC1 'copyright' 

both work for this eglibc.

NOTE: The Debian package utility dpkg-shlibdeps uses objdump under the hood, along with stored symbol information in Debian library packages to determine the minimum versions of dependencies required by binary Debian packages at build time. Basically, it looks at the symbols exported by the binary Debian package, and then finds the minimum versions of the libraries that contain those symbols.

Читайте также:  Vhd to hdd linux

The obvious answer, though not the most comprehensive, is to check your package manager, e.g

rpm -qi glibc dpkg -l libc6 

(Sadly, glibc doesn’t have a pkconfig .pc file, so pkgconfig —modversion glibc is a non-runner.) See also @Gnouc’s excellent getconf suggestion.

The simplest case, with gcc+glibc, and the one I mostly use first is to just execute libc.so , as outlined in some of the other answers here. There’s no need to pass any arguments, it outputs its version by default. This works back as far as glibc-2.1 (glibc-2.0 seg-faults, though way back then you could check the (now retired) glibcbug script to confirm the version). This method also works with recent (>0.9.15) versions of musl-libc (which just went 1.0 today, March 20th). It does not work with uClibc, it segfaults.

One simple way to tell exactly what your gcc is going to do is compile:

#include #include int main(int argc, char *argv[])

(with glibc, includes which defines the relevant GLIBC macros, you need for the function declarations.)

This catches more complex cases (multiple libc’s, and/or multiple compilers), assuming you’re using the right compiler (and flags) of course. (I suspect it won’t distinguish between eglibc and glibc proper though.)

If you are certain you are using glibc (or eglibc) then ld will also confirm the version (sorry, this is not correct).

If __GNU_LIBRARY__ is not defined you will get errors, then it’s time for plan B.

gcc -dumpmachine may help, e.g. for uclibc it has a -uclibc suffix, as may gcc -dumpspecs | grep dynamic-linker . This also may imply the ABI.

gcc -print-file-name=libc.so will tell you what file the compiler will use for » -lc «, this is almost certainly a linker-script within your gcc installation, which you can read it as plain text. That will show the exact path to libc.so . This will also work if you’re passing flags like -m32 or -m64 .

In the event you’re using uclibc (as used by OpenWRT and more), it defines __UCLIBC_MAJOR__ , __UCLIBC_MINOR__ and __UCLIBC_SUBLEVEL__ as well as __UCLIBC__ in , so it’s easily detected using a minor variation on the above C code snippet. In the interest of compatibility, uClibc may also define the GNU/GLIBC macros as used above, it currently pretends to be glibc-2.2. It does not currently implement the gnu_get_libc_X() functions, but it does implement getconf which may also mislead (I suspect it returns an empty answer for getconf GNU_LIBC_VERSION , my build env is sulking today so I cannot confirm.)

Читайте также:  Запуск jar приложения linux

In the unlikely event you’re using dietlibc, running diet -v will display the version.

(FWIW, over several years with software using autoconf I’ve had more problems with unchecked-for gcc and g++ requirements than with checked-for glibc features.)

Источник

How to do versioning of shared library?

Windows provides the resource file for version information for an application and DLL. The resource file includes information like version, copyright and manufacturer. We have a shared library and would like to add version information. How can we do it on Linux with a shared library?

3 Answers 3

The short version is that you do this via the soname of the library. Read chapter 3 at http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html as well as chapter 3.3 ABI Versioning at http://www.akkadia.org/drepper/dsohowto.pdf

Thanks for your answer, I was redirected from here but I still don’t understand how one program can understand which library version to use. I want that one program use one version and another the new version.

One comment on the Program-Library-HOWTO: if you are writting receipt for install in makefile, you should do nothing other than generating & copying files into destination dir. so do not call ldconfig in receipt, just create symbolic link file with soname to realname (for your bin-package) and create linkname to soname (for your dev-package), and installer can call ldconfig by themselves after «make install» if they install the library into non-standard location. because «make install» may be invoked for cross-compiling

The best way to handle this is using libtool, which does the versioning for you.

Essentially, version information is not (or not primarily, don’t know from my head) encoded in the library itself, but rather in its filename. Version numbers are normally given in three-dot format, with the major number increasing for each break in downward ABI compatibility, the middle for breaks in upward ABI compatibility, and the minor for patches that did not change the ABI.

Like qdot noted, symlinks in the lib directory provide the essential versioning. There is a symlink without a version number (libfoo.so) for the currently installed development headers, a symlink with a major number for each installed major version (libfoo.so.1) and a real file with the full version number. Normally, programs are linked to use libfoo.so.1 at runtime so that multiple major versions may coexist.

Источник

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