It's pretty detailed. Note: ln command usage ln–s source file destination file (the destination file is a soft link file) available ls-l see which file the soft link file points to
Catalogue [-]
- 1. File libhello.c
- 2. File libhello.h
- 3. File MAIN.C
Objective
Links and loads for different versions of the same dynamic component.
First, the concept
DLL Hell literally means DLL "disaster", which is due to the fact that the COM component (Dynamic Library) upgrade causes the program not to run.
Reason
There are three possible causes for DLL Hell to occur:
One is caused by replacing a new version of a DLL with an older DLL. This is one of the most common causes of DLL errors that Windows 9X users typically encounter.
The second is caused by the unintended change of functions in the new DLL. Although it should be backwards compatible when designing DLLs, it is not possible to ensure that DLLs are fully backwards compatible.
The third is the introduction of a new version of the DLL installation bug.
Ii. Solutions under Linux-naming conventions
DLL on Linux, called Sharedlibrary. Linux systems face the same problems as window, and how to control multiple versions of a dynamic library. To solve this problem, Linux has introduced a set of naming mechanisms to solve this problem, which can be avoided if this mechanism is followed. But it's an agreement, not a compulsion. However, it is recommended to adhere to this Convention, otherwise the Linux version of the DLL Hell problem will also appear.
Real Name
The first is the file name of the shared library itself: the name of the shared library must be preceded by the prefix "Lib", which is the name of the library and the suffix ". So", and the last three digits are the version number libname.so.x.y.z. X is the major version (Major version number), Y is the minor version (Minor version number), and Z is the release version number.
Major version number (incompatible): Significant upgrade, libraries between different major versions of libraries are incompatible. Therefore, if you want to ensure backward compatibility, you cannot delete the old dynamic library version.
Minor version number (backwards compatible): Incremental upgrade, adding some new interfaces but preserving the original interface. Libraries with higher version numbers are backward compatible with lower version numbers.
Release version number (compatible with each other): Some of the libraries, such as error modification, performance improvements, and so on, do not add new interfaces or change interfaces. The major and minor version numbers are the same, and are fully compatible with each release version.
So-name
Strict adherence to the above rules can indeed avoid the issue of the dynamic library because of version conflicts, but the reader may have questions: when the program loads or runs, how does the dynamic linker know which libraries the program depends on, and how to choose different versions of the library?
The So-name (shortfor shared object name) naming mechanism, such as Solaris and Linux, is used to record the dependencies of shared libraries. Each shared library has a corresponding "So-name" (the shared library file name is stripped of the minor version number and the release version number). For example, a shared library named libtest.so.3.8.2, then its so-name is libtest.so.3.
In a Linux system, the system creates a soft connection (Symbol link) that is the same as so-name for each directory in which the shared library resides. This soft connection will point to the shared library with the same major version number, minor version number, and release version number in the directory. In other words, for example, there are two shared library versions in the directory:/lib/libtest.so.3.8.2 and/lib/libtest.so.3.7.5, soft connect/lib/libtest.so.3 point to/lib/libtest.so.3.8.2.
The purpose of establishing a soft connection with the name So-name is to make all modules dependent on a shared library use the so-name of the shared library when compiling, linking, and running, rather than using a detailed version number. When compiling the production elf file, if file a depends on file B, then the ". Dynamic" segment in A's link file will have a field of type Dt_need, and the value of the field is So-name of B. This enables the dynamic linker to automatically direct to the latest compatible version of the shared library based on the So-name soft connection in the various shared library directories in the system when the shared library relies on file lookups.
★readelf-d sharelibrary can view So-name
★linux provides a tool to--ldconfig when a shared library is installed or updated in the system, it will traverse the default all shared library directories, such as/lib,/usr/lib, and then update all soft links so that they point to the latest shared library.
Link Name
When we use the shared library in the compiler, such as the "-l" parameter of GCC to link shared library libtxxx.so.3.8.1, only need to specify the compiler command line-l XXX, omit the prefix and version information. The compiler looks for the latest version of the XXX library based on the current environment, in the relevant path in the system (often specified by the-l parameter). This xxx is the "link name" of the shared library. Different types of libraries may have the same link name, for example, the C runtime has a static version (LIBC.A) and a dynamic version (LIBC.SO.X.Y.Z), if the parameter "-LC" is used when linking, then the connector will select the appropriate version of the library based on the case of the output file (dynamic/static). eg. When LD uses the "-static" parameter, "-LC" looks for LIBC.A, and if you use "-bdynamic" (the default), the latest version of libc.so.x.y.z is found.
More details can be found in
Http://www.linuxidc.com/Linux/2012-04/59071.htm
Code:
1. File libhello.c
/* Hello.c-demonstrate library use. */
#include <stdio.h>
void Hello (void)
{printf ("Hello, library world./n");}
2. File libhello.h
/* Libhello.h-demonstrate library use. */
void Hello (void);
3. File MAIN.C
/* MAIN.C--demonstrate direct use of the "hello" routine */
#include "hello.h"
int main (void)
{
Hello ();
return 0;
}
1. Generate a shared library, associated with real name and Soname.
Gcc-g-wall-fpic-c Hello.c-o hello.o
Gcc-shared-w,soname,-libhello.so.0-o libhello.so.0.0.0 hello.o
The shared library libhello.so.0.0.0 will be generated.
You can view the header of a shared library with a system-provided tool:
Readelf-d libhello.so.0.0.0 | grep Libhello
ox00000000000e (SONAME) library SONAME: [libhello.so.0]
2. Applications, referencing shared libraries.
The link name is generated manually before being linked by the following program
Ln-s libhello.so.0.0.0 libhello.so.0
Gcc-g-wall-c main.c-o main.o-i.
Gcc-o main main.o-lhello-l.
(I'll have a problem here.) because: When executing gcc-o main main.o-lhello-l. command, the default is to find libhello.so this file, but obviously no, direct error. I also do:
Ln-s libhello.so.0.0.0 libhello.so After, can, until now, do not understand why? )
To view the compiled program:
readelf-d Main | grep Libhello
OX000000000001 (NEEDED) shared library: [libhello.so.0]
To run the program, you need to specify the path to the shared library. There are two ways to use the environment variable "Ld_library_path" in the first case. One way to do this is to copy the shared library to the system directory (one of the directories specified by the PATH environment variable).
Time out! We have not solved a problem is that the program only know Soname, how to find the shared library from Soname, that is, the real name file? This requires that we define a link file to connect to the shared library itself.
Ln-s libhello.so.0.0.0 libhello.so.0
Of course, this path needs to be placed in the LD_LIBRARY_PATH environment variable.
This allows you to run the program.
[Note] The Linux system provides a command LDCONIFG specifically for generating soname files for shared libraries so that the program can find shared libraries through soname after loading. At the same time, the command also to speed up the loading of shared libraries, the system's shared library into a cache file, which can improve the search speed. You can use the following command to look at the system's existing cached shared libraries.
Ld-p
To run the program:
./main this way, running directly is not working. The dynamic library must also specify the path at run time. So, copy the. So file to/lib or/usr/lib, then execute the ldconfig/lib command and it's OK.
(
Ldconfig is a dynamic link Library management command
In order for the dynamic link library to be shared with the system, it is also necessary to run the management commands of the dynamic link library--ldconfig
The purpose of the Ldconfig command is to search for a shareable dynamic-link library (in the form of a previous introduction, lib*.so*), mainly in the default search directory (/lib and/usr/lib) and in the directory listed in the dynamic library configuration file/etc/ld.so.conf. This creates the connection and cache files required by the dynamic loader (ld.so). The cache file defaults to/etc/ld.so.cache, which holds the list of queued dynamic-link library names.
Ldconfig usually runs at system startup, and when a user installs a new dynamic link library, they need to run the command manually.)
3. Shared library, minor version upgrade, that is, the interface is unchanged.
When you upgrade a iteration, the soname of the shared library is constant, so you need to re-specify the new version of the Soname connection file. Call the Ldconfig command and the system will help you modify that soname link file and point it to the new version. Your application will be upgraded automatically at this time.
4. Shared library, major version upgrade, that is, the interface has changed.
When the major version is upgraded, the soname of the shared library will be added 1. For example, libhello.so.0.0.0 becomes libhello.so.1.0.0. When you run the Ldconfig file again, you will find that two connection files are generated.
Ln-s libhello.so.0---->libhello.so.0.0.0
Ln-s libhello.so.1----->libhello.so.1.0.0
Although the shared library is upgraded, your program still uses the old shared library, and the two does not affect each other.
The problem is that if the updated shared library only adds some interfaces, it does not modify the existing interface, which is forward compatible. But this time its main version number was increased by 1. What if your application wants to invoke a new shared library? Simply, just manually modify the Soname file so that it points to the new version. (This time Ldconfig file will not help you do such a thing, because this time soname and real name version number of the motherboard is inconsistent, can only be manually modified).
For example: Ln-s libhello.so.0---> libhello.so.1.0.0
However, there are times when the major version number increases, the interface changes, and may be forward incompatible. At this time again such a modification, will be error, "XX" method can not find such errors.
To summarize, the Linux system manages multiple versions of a shared library by sharing three different names for the library. Real name is the actual file name of the shared library, and Soname is the file name used when the shared library is loaded. When building a shared library, the compiler binds the soname to the file header of the shared library. When the application references a shared library, it is done through link name, and link will search for the link name in the directory specified by the system to find the shared library and write the soname of the shared library in the application's header file. When the application loads the shared library, it looks for the shared library through Soname in the system-specified directory (path or ld_library).
When a shared library is upgraded, it is divided into two types. One is the motherboard unchanged, the upgrade iteration and build number. In this case, the system will use the new version number by updating Soname (Ldconfig to maintain). In this case, the old version is useless and can be deleted.
The other is the main version upgrade, which means that the library interface changes, of course, this time can not overwrite the existing soname. The system makes the new and old versions exist by adding a soname (ldconfig-p). The original application, when loading, is still looking for old library files based on the old soname of their header files.
5. What happens if the soname of the shared library is not specified when compiling?
This is a trick place. The first system will have no soname placed in the library's head when the library is built. When the application connects, the linkname is placed in the application-dependent library. Or in other words, Soname does not have a version number at this time. Sometimes someone directly use this to upgrade the application, for example, the new version of the library, directly copied to the system directory, will overwrite the existing old library files, directly upgrade. This gives the programmer a great degree of convenience, and if one step is careful, it will be transferred to the Windows-like DLL Hell trap. It is recommended that you do not do so.
"Note"
1. Specify the path that the shared library loads. The Ld_library_path takes precedence over the PATH environment variable.
2. LDD can view the program, or the path of the library to which the shared library depends
3. NM View shared library exposed interfaces
4. Ldconfig can automatically generate Soname connection files. and provides catch-accelerated lookups.
5.readelf can view the information of the dynamic library, such as the dependent library, its own soname.
6. Objdump is similar to readelf.
7 LD the GUN linker
8. LD.SO Dynamic linker or loader
9. As the portable GNU Assembley
"Reference"
Http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
Linux Summary 13th: Dynamic Library and version number control under Linux