Can someone explain about Linux library naming?
From an old email I sent to a colleague about this question:
Let's look at libxml as an example. First of all, shared
objects are stored in /usr/lib with a series of symlinks to represent
the version of the library availiable:
lrwxrwxrwx 1 root root 16 Apr 4 2002 libxml.so -> libxml.so.1.8.14
lrwxrwxrwx 1 root root 16 Apr 4 2002 libxml.so.1 -> libxml.so.1.8.14
-rwxr-xr-x 1 root root 498438 Aug 13 2001 libxml.so.1.8.14
If I'm the author of libxml and I come out with a new version, libxml
2.0.0 that breaks interface compatiblity with the previous version, I
can install it as libxml.so.2, and libxml.so.2.0.0. Note that it is
up to the application programmer to be responsible about what he links
to. If I'm really anal, I can link directly to libxml.so.1.8.14 and
any other version will result in my program not running. Or I can
link against libxml.so.1 and hope that the libxml developer doesn't
break symbol compatibility on me in the 1.X version. Or if you don't
care and are reckless, just link to libxml.so and get whatever version
there is. Sometimes, when enough people do this, the library author
has to get creative with later versions. Hence, libxml2:
lrwxrwxrwx 1 root root 17 Apr 4 2002 libxml2.so.2 -> libxml2.so.2.4.10
-rwxr-xr-x 1 root root 692727 Nov 13 2001 libxml2.so.2.4.10
Note that there's no libxml2.so in this one. Looks like the developer
got fed up with irresponsible application developers.
Is lib{library name}.a / .so a naming convention for static libraries in Linux?
You can name one any way you want, but ld
's -l
assuming a lib
prefix applies to both static and shared libraries and goes back a long way; you'd need to name it explicitly to use one without the lib
prefix.
This is actually useful even on modern systems: a name libfoo.so
can be identified as a link-time library, while foo.so
indicates a shared object implementing a runtime plugin. Or subsystem-specific prefixes in place of lib
to identify plugins for particular subsystems; see for example pam_*.so
and nss_*.so
.
Linux library naming conventions: Capitalization?
I think it's rather an inherited culture than a convention itself. Default filenames of Unix systems are predominantly written in lowercase. That came for some historical reasons.
Some file systems are case insensitive and if you share Linux files to OSs that has case insensitive file systems you can get some conflicts.
If you have three files: someFile.txt, SomeFile.txt, somefile.txt
In Linux you have three files with different names, but in an OS that use HFS+ (present on MACs), VFAT, FAT32, FAT12 (present in old versions of MSDOS and Windows) you have three files with the same name (somefile.txt), thus you will have filename conflicts.
The C community adopt lower-case as a convention to the C-libraries. A lot of influent C programmers integrate the community that initiated the development of applications for Unix.
A last funny reason, programmers are lazy. Use the shift or Caps-lock key, unless it's necessary, isn't cool.
How should I conventionally name a linux-based C++ library?
A library is not the same as the Debian/Ubuntu package providing it.
The libfoo-dev
(so called development) package often provides some header files and the static library (needed to build source programs using that library).
The libfoo
package is providing the shared libraries (needed by other programs and packages to run).
Often the libfoo-dev
package is depending upon its libfoo
package.
How to find what library name should I use
Look into the documentation; for man pow
you will read
Link with -lm.
for man pthread_yield
you will read
Compile and link with -pthread.
Such a documentation does not exist everytime; you might have to look at other places too (e.g. pdf, info pages, web sites).
Shared library name in executable is different than the filename
Could that be true?
This is often true.
On ELF systems, the linker uses SONAME
of the library (if it has one) and not its filename to record a runtime dependency.
Running readelf -d libnvrtc-5e8a26c9.so.10.1 | grep SONAME
will likely show that in fact that library does have SONAME
, and the value of SONAME
is libnvrtc.so.10.1
.
This used to be very convenient for external library versioning.
Update:
it allows you to link against a library which will be different than the one which will used at run time, but why would I ever want that?
Like I said, it's useful for external library versioning and ABI evolution.
Suppose you ship version 1.0 of libfoo.so
. You provide libfoo.so
as a symlink to libfoo.so.1
, and you use libfoo.so.1
as SONAME
.
Any program that links with gcc main.c -lfoo
(note: no funny -l:libfoo.so.1
syntax required) will record libfoo.so.1
as its external dependency, and will use that name at runtime.
Time passes, and you are ready to ship version 2, which is not ABI-compatible.
You don't want to cause all your end-users to change their link line, and you don't want to break any existing binaries.
With the SONAME
, this is trivial: new package will include libfoo.so.2
with SONAME
of libfoo.so.2
, and a symlink libfoo.so
now pointing to libfoo.so.2
.
Voila: both requirements are achieved: existing binaries continue to use libfoo.so.1
, newly-linked binaries use libfoo.so.2
, no Makefile
changes required.
Related Topics
Under What Circumstances Is It Advantageous to Give an Implementation of a Pure Virtual Function
Why "Long Int" Has Same Size as "Int"? Does This Modifier Works at All
Communication Between Native-App and Chrome-Extension
How to Call a C++ Method from C
Boost Interprocess Mutexes and Checking for Abandonment
Virtual Functions Default Parameters
Understanding Y Combinator Through Generic Lambdas
Why Do You Need to Append an L or F After a Value Assigned to a C++ Constant
How to Initialize All Tuple Elements by the Same Arguments
Boost Spirit X3: Parse into Structs
Why Do My Sfinae Expressions No Longer Work with Gcc 8.2
In C++, Is There a Difference Between "Throw" and "Throw Ex"
Is There a Default Hash Function for an Unordered_Set of a Custom Class
Communicate with Codesys Program on a Linux-Based Wago Pfc200 Plc
Cmake Error: "Add_Subdirectory Not Given a Binary Directory"
Unordered_Map Constructor Error (Equal_To Templated Function)