Analysis of Linux static and dynamic libraries

  

Libraries are dynamic and static. Dynamics usually use .so as a suffix and static as a suffix.

Example: libhello.so libhello.a In order to use different versions of the library in the same system, you can add the version number to the suffix after the library file name, for example: libhello.so.1.0, due to program connection default Use .so as the file extension. So in order to use these libraries, it is common to use a way to establish symbolic connections.

$ln -s libhello.so.1.0 libhello.so.1 //I don't know what is the use of libhello.so.1 in this place? ?

$ln -s libhello.so.1 libhello.so

1. Using the library

When you want to use a static library, the connector will find the program. The required functions are then copied to the executable file. Since this copy is complete, once the connection is successful, the static library is no longer needed. However, for dynamic libraries, this is not the case. The dynamic library leaves a flag in the executable that indicates that the library must first be loaded when the program executes. Since the dynamic library saves space, the default operation for connecting under Linux is to connect the dynamic library first, that is, if there are static and dynamic libraries at the same time, if it is not specified, it will be connected with the dynamic library.

Now suppose that there is a program development package called hello, which provides a static library libhello.a a dynamic library libhello.so, a header file hello.h, the header file provides sayhello () this function: < Br>

/*hello.h */

void sayhello();

There are some other documentation.

This is a typical program development package structure. Linux defaults to the dynamic library connection, the following program testlib.c uses the sayhello() function in the hello library

/*testlib.c*/

#include <stdio.h> ;

#include "hello.h"

int main() { sayhello(); return 0; }

Use the following command to compile $gcc -c testlib .c -o testlib.o

Connect with the following command: $gcc testlib.o -lhello -o testlib

Be careful when connecting, suppose libhello.o and libhello.a are missing Under the library search path under /usr/lib, if you want to add -L parameter to other locations

, it is more troublesome to connect with the static library, mainly the parameter problem. Or the above example:

$gcc testlib.o -o testlib -WI,-Bstatic -lhello # -WI,-Bstatic has no effect on my machine, changed to -static effective

Note: This special "-WI,-Bstatic" parameter is actually passed to the connector ld. Indicates that it is connected to the static library. If there is only a static library in the system, of course, this parameter is not needed. If you want to connect to multiple libraries, and each library is connected differently, for example, the above program should be statically connected with libhello and dynamically connected with libbye. The command should be:

$gcc testlib.o -o testlib -WI,-Bstatic -lhello -WI,-Bdynamic -lbye

2. Path Problems for Dynamic Libraries In order for the executable to find dynamic libraries smoothly, there are three ways:

(1) Copy the library to the /usr/lib and /lib directories.

(2) Add the path of the library in the LD_LIBRARY_PATH environment variable. For example, the dynamic library libhello.so is in the /home/ting/lib directory, using bash as an example. Use the command:

$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib

( 3) Modify the /etc/ld.so.conf file, add the path where the library is located to the end of the file, and execute ldconfig to refresh. This way, all library files in the joined directory are visible.

3. Viewing symbols in the library

Sometimes it may be necessary to see which functions are in a library. The nm command can print out all the symbols involved in the library. Libraries can be either static or dynamic. There are many symbols listed in nm, there are three common ones, one is called in the library, but not defined in the library (indicating that other library support is needed), represented by U; one is the function defined in the library, This is the most common with T; the other is the so-called "weak" symbols, which are defined in the library but may be covered by symbols of the same name in other libraries, denoted by W. For example, suppose the developer wants to know if printf() is defined in the hello library mentioned above:

$nm libhello.so |  Grep printf U

where printf U indicates that the symbol printf is referenced, but it is not defined in the function. It can be inferred that to use the hello library normally, there must be other library support, and then use the ldd command to view the hello dependency. Which libraries are available:

$ldd hello libc.so.6=>/lib/libc.so.6(0×400la000)/lib/ld-linux.so.2=>/lib/Ld-linux.so.2 (0×40000000) From the above results you can continue to see where printf is finally defined, interested can go on

4, build library

The source code is compiled into the target code. Take the following code as an example to generate the hello library used above:

/* hello.c */

#include <stdio.h>

void sayhello () { printf(”hello,world “); }

Edit this file with gcc, you can use any legal editing parameters when editing, such as -g to add debugging code, etc.

1. Connect to a static library to connect to a static library using the ar command. In fact, ar is archive meaning $ar cqs libhello.a hello.o2. Connecting to a dynamic library to generate dynamic libraries is done with gcc, as there may be many Versions, so usually specify the version number:

$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o

Add another two Symbolic links:

$ln -s libhello.so.1.0 libhello.so.1

$ln -s libhello.so.1 libhello.so

Libhello's dynamic link library is generated. The most important thing is to pass the gcc -shared parameter to make it a dynamic library instead of a normal executor. -Wl indicates that the following parameter is -soname, libhello.so.1 is passed directly to the connector ld for processing. In fact, each library has a soname. When the connector finds a name in the library it is looking for, the connector will embed the soname in the binary in the link instead of the actual file name it is running. During program execution, the program looks for a file with the name of the soname, not the file name of the library. In other words, soname is the distinguishing flag of the library. The purpose of this is to allow multiple versions of the library files to coexist in the system. It is customary to use the same libxxxx.so.major.minor when naming the library files. xxxx is the name of the library, and major is the major version number. Minor is the minor version number

Copyright © Windows knowledge All Rights Reserved