The concept of Linux library, the production of dynamic library and static library, how to transplant third-party library Reprinted by Wei Dongshan

Yikoujun's favorite song in middle school.

Dou Xian is brilliant, unrestrained, uncontested, cool on the outside and tender on the inside!

Let's learn what a (cool) library is with Dou Xian's high voice!

1. What is a library?

There are a large number of libraries under both the windows platform and the linux platform. Generally, it is a set of binary relocatable object code files released by the software author for the convenience of distribution, replacement or secondary development, which can be linked with the application program at compile time or runtime.

In essence, a library is a binary form of executable code. This file can be directly linked into the executable program by the compiler at compile time, or it can be dynamically loaded into memory by the runtime environment of the operating system as needed at runtime.

A set of libraries forms a release package. Of course, how many libraries to release is entirely up to the library provider.

Due to the different nature of windows and linux, the binaries of the two libraries are not compatible.

In reality, every program depends on many basic underlying libraries. It is impossible for everyone to start from scratch, so the existence of the library is very meaningful.

The advantage of the shared library is that if different applications call the same library, there is only one instance of the shared library in memory.

This article only discusses the library under linux.

Second, the classification of the library

There are two types of libraries: static libraries and shared libraries (dynamic libraries).

win32平台下,静态库通常后缀为.lib,动态库为.dll ;
linux平台下,静态库通常后缀为.a,动态库为.so 。

In essence, there is no difference in function between the static library and the dynamic library compiled by the same program. The difference lies only in their names, namely "static" and "dynamic".

Both exist in the form of a file, which is essentially a binary format of executable code that can be loaded into memory for execution. Whether it is a dynamic link library or a static link library, they are nothing more than providing variables, functions and classes to their callers.

1. Static library

The so-called static library means that the compiler searches for and links to the specified directory during static compilation. Once the link is completed, the final executable program contains all useful information in the library file, including code segments, data segments, etc.

2. Dynamic library

The so-called dynamic library means that when the application program is running, the operating system dynamically searches for and loads it into the memory under the specified directory according to the request of the application program, and at the same time needs to perform address redirection.

3. Difference

We discuss the difference between static libraries and dynamic libraries at two points: compilation link and loading time .

compile link

The static link library will be linked into the target code when the program is compiled, and the dynamic library will no longer need to be changed when the target program is running. It is linked into an executable file, which leads to a larger executable file size.

The dynamic library is not linked into the object code when the program is compiled, but is loaded when the program is running, because the executable file is small in size. With a dynamic library, program upgrades will be relatively simple. For example, if a dynamic library is upgraded, only the files of the dynamic library need to be replaced, and there is no need to replace the executable file. But it should be noted that the executable program needs to be able to find the dynamic library file at runtime. The executable file is the caller of the dynamic library.

picture

Program Code and Libraries

loading time

The difference between the two lies in the moment when the code is loaded. The code of the static library has been loaded into the executable program during the compilation process, so the size is relatively large. The code of the shared library is loaded into the memory when the executable program is running, and is simply referenced during the compilation process, so the code size is small.

4. Advantages and disadvantages

Compared with the dynamic library, the advantage of the static library is that it is directly linked into the executable program. After that, the executable program no longer depends on the settings of the operating environment (of course it still depends on the CPU instruction set and the executable program supported by the operating system). enforce hard restrictions such as file format).

The advantage of the dynamic library is that the user can even replace the dynamic library at any time when the program is running, which forms the basis of the dynamic plug-in system. The specific use of static libraries and dynamic libraries is determined by the programmer according to the needs.

3. Production of library files

1. Library file naming

The name of the static library is generally libxxxx.a, where xxxx is the name of the lib; the name of the dynamic library is generally libxxxx.so.xyz, the meaning is shown in the following figure:picture

2. Common parameters for making library files

First of all, it is important to understand that some parameters are used to compile the gcc library.

parameter meaning
-shared Specifies to generate a dynamic link library.
-static Specifies to generate a static link library.
-fPIC Indicates compilation to position-independent code for compiling shared libraries. Object files need to be created as position-independent code, which conceptually means that they can be placed anywhere in the executable's memory when the executable loads them.
-L Indicates that the library to be linked is in the current directory.
-l Specifies the dynamic library required for linking. There is an implicit naming rule when the compiler looks for a dynamic link library, that is, add lib before the given name, and add .so after it to determine the name of the library.
-Wall Generate all warning messages.
-ggdb This option will generate as much debugging information as possible for gdb to use.
-g The compiler generates debugging information when compiling.
-c Only activate preprocessing, compilation and assembly, that is, make the program into an object file (.o file).
-Wl,options Pass the parameters (options) to the linker ld. If there is a comma in the middle of options, the options are divided into multiple options, and then passed to the linker.

3. Library source files

Suppose we want to make the following two files into a library file add.c

int add(int x,int y)
{
     return x+y;
}
int sub(int x,int y)
{
     return x-y;
}

add.h

int add(int x,int y);
int sub(int x,int y);

4. Make a static library and use it

  1. Need to compile add.c into .o file

gcc -c add.c
  1. Use the ar command to generate a static library libadd.a

ar -rc libadd.a add.o      遵循静态库命名的规则 lib + 名字 + .a
  1. Using the static library If you use the static library libadd.a, you only need to include add.h, and you can use the functions add() and sub().

#include <stdio.h>
#include "add.h"
void main()
{
    printf("add(5,4) is %d\n",add(5,4));
    printf("sub(5,4) is %d\n",sub(5,4));
}

The file of the static library can be placed in any location, and only need to find the library file when compiling.

gcc test.c -o run libadd.a
  1. If the library and header files are in other directories

Compile with:

gcc -c -I /home/xxxx/include test.c //假设test.c要使用对应的静态库
gcc -o test -L /home/xxxxx/lib test.o libadd.a

or

gcc -c -I /home/xxxx/include -L /home/xxxxx/lib  libadd.a test.c

1). Specify the corresponding header file through -I (is big i) 2). Specify the path of the library file through -L, libadd.a is the static library to be used. 3). The header file of the static library should be included in test.c.

5. Create a dynamic library and use it

  1. Compile add.c into dynamic link library libadd.so

gcc -fPIC -o libadd.o -c add.c
gcc -shared -o libadd.so libadd.o

You can also directly use a command

gcc -fPIC -shared -o libadd.so add.c
  1. The installation of the dynamic library is usually done by copying the dynamic library to /lib:

sudo cp libadd.so /lib
  1. Use dynamic library

#include <stdio.h>
#include "add.h"
void main()
{
    printf("add(5,4) is %d\n",add(5,4));
    printf("sub(5,4) is %d\n",sub(5,4));
}

Compile the dynamic library:

gcc static -o run  -ladd

Pay attention to the corresponding relationship between the name of the dynamic library and the library file at compile time

libadd.so<--------->-ladd

Remove .so, simplify lib to l, and keep other letters.

6. Dynamically Loaded (DL) Libraries

Dynamically loaded libraries Dynamically loaded (DL) libraries are a class of libraries that can be loaded at any time during program execution. They are especially suitable for loading some modules and plugin extension modules in the function, because it can be dynamically loaded when the program needs a certain plugin module.

Under the Linux system, there is no special difference in the format between the DL function library and other function libraries, and they are created in the standard object format. The main difference is that these function libraries are not loaded when the program is linked or started, but through an API to open a function library, find the symbol table, handle errors and close the function library. Usually in the C language environment, this header file needs to be included.

dlopen()

The dlopen function opens a function library and prepares it for later use. The C language prototype is:

 void * dlopen(const char *filename, int flag);
 参数

filename
如果文件名filename是以“/”开头,也就是使用绝对路径,那么dlopne就直接使用它,而不去查找某些环境变量或者系统设置的函数库所在的目录了。否则dlopen()就会按照下面的次序查找函数库文件:
1. 环境变量LD_LIBRARY指明的路径。
2. /etc/ld.so.cache中的函数库列表。
3. /lib目录,然后/usr/lib。

一些很老的a.out的loader则是采用相反的次序,也就是先查 /usr/lib,然后是/lib。

flag
的值必须是RTLD_LAZY或者RTLD_NOW,RTLD_LAZY的意思是resolve undefined symbols as code from the dynamic library is executed,而RTLD_NOW的含义是resolve all undefined symbols before dlopen() returns and fail if this cannot be done'。
返回值
dlopen()函数的返回值是一个句柄,然后后面的函数就通过使用这个句柄来做进一步的操作。如果打开失败dlopen()就返回一个NULL。如果一个函数库被多次打开,它会返回同样的句柄。 

If there are several function libraries and there are some dependencies among them, for example, X depends on Y, then you need to load those dependent functions first. For example load Y first, then load X.

dlerror()

By calling the dlerror() function, we can get the error message of the last call to dlopen(), dlsym(), or dlclose().

dlsym()

If you load a DL function library and don't use it, it is of course impossible. The most important function to use a DL function library is dlsym(). This function searches for a given symbol in an already opened function library. . This function is defined as follows:

 void * dlsym(void *handle, char *symbol);
参数
handle
就是由dlopen打开后返回的句柄,
symbol
是一个以NIL结尾的字符串。
功能:
如果dlsym()函数没有找到需要查找的symbol,则返回NULL。如果你知道某个symbol的值不可能是NULL或者0,那么就很好,你就可以根据这个返回结果判断查找的symbol是否存在了;不过,如果某个symbol的值就是NULL,那么这个判断就有问题了。标准的判断方法是先调用dlerror(),清除以前可能存在的错误,然后调用dlsym()来访问一个symbol,然后再调用dlerror()来判断是否出现了错误。

dlclose()

The reverse process of the dlopen() function is the dlclose() function, which forcibly closes a DL function library. The Dl function library maintains a resource utilization counter. When dlclose is called, the count of this counter is decremented by one. If the counter is 0, it is actually released. When it is actually released, if there is a function _fini() in the function library, the function _fini() will be called automatically to do some necessary processing. Dlclose() returns 0 for success, other non-zero values ​​for errors.

example

#include <stdio.h>
#include <dlfcn.h>
void main()
{
    int (*add)(int x,int y);
    int (*sub)(int x,int y);
    void *libptr;
    libptr=dlopen("./libadd.so",RTLD_LAZY); //加载动态库
    add=dlsym(libptr,"add"); //获取函数地址
    sub=dlsym(libptr,"sub");
    printf("add(5,4) is %d\n",add(5,4));
    printf("sub(5,4) is %d\n",sub(5,4));
    dlclose(libptr);
}

4. Two viewing commands of the library

  1. View dependent library command ldd

Use the ldd command to see which libraries an executable program depends on.

This command is very useful. In actual work, various libraries are often used all the time, and the execution of some programs needs to rely on several libraries. There are many historical versions of various libraries, and library incompatibility often occurs. We need to base on the actual The situation, appropriately reduce or upgrade the version.

For example:picture

You can see that the thread library libpthread-2.23.so depends on the libc library and the ld-linux library.

  1. nm

The nm tool can print out all the symbols involved in the library. Here is the dynamic library libadd.a we created:

picture

nm

5. Library installation

How to make the system find him after installing a new library, there are several methods:

1. Copy to /lib or /usr/lib

If it is installed under /lib or /usr/lib, then ld can find it by default, no other operations are required. If it is installed in another directory, it needs to be added to the /etc/ld.so.cache file, the steps are as follows

2. Through the configuration file /etc/profile

For permanent environment variable settings, edit /etc/profile.

 vi /etc/profile

Add the corresponding environment variable information at the end of the file.

Dynamic library environment variable settings:

export LD_LIBRARY_PATH=/home/peng/mylib/

/home/peng/mylib/ refers to the location of the dynamic library folder. That is, files such as .so are under /home/peng/mylib/.

Editing is complete, save the edits and exit; make the configuration take effect immediately:

source /etc/profile

3./etc/ld.so.conf

Edit the /etc/ld.so.conf file and add the path of the directory where the library file is located

vim /etc/ld.so.conf

Just add the path of the dynamic library in it, for example

/usr/local/lib/

Run ldconfig, which will rebuild the /etc/ld.so.cache file

7. Transplantation of common libraries

1.jpeg library for jpeg image processing

download link:

http://www.ijg.org/files/

decompress

tar xvzf jpegsrc.v6b.tar.gz
cd jpeg-6b

Generate Makefile

./configure --host=arm-linux-gnueabihf --prefix=$PWD/temp_install

compile, install

 make
 make install

Note that the installation program of this library has a BUG, ​​and will not automatically create released lib, include, man, etc., so it must be created manually, or do other libraries first, and then install this library

 mkdir -p /home/peng/jpeg-6b/temp_install/include
 mkdir -p /home/peng/jpeg-6b/temp_install/lib
 mkdir -p /home/peng/jpeg-6b/temp_install/man/man1  

Guess you like

Origin blog.csdn.net/volval/article/details/113306953