Dynamic and static libraries under linux (necessary for beginners)

1. Basic concepts of dynamic and static libraries

1. Dynamic library: Under Linux, the dynamic library is a file suffixed with .so. The dynamic library is not linked to the object code when the program is compiled, but is loaded when the program is running. If different applications call the same library, there is only one instance of the shared library in memory, which avoids the problem of wasting space. The dynamic library is only loaded when the program is running, which also solves the trouble that the static library will bring to the program's update, deployment and release pages. Users only need to update the dynamic library, incremental update.

2. Static library: Under Linux, a static library is a file with a suffix of .a. When the program is compiled and linked, a copy of the code in the library will be put into our executable program.

3. Static linking: The process of copying the code in the library to the executable program.

4. Dynamic linking: Before the executable file starts running, the machine code of the external function is copied from the dynamic library on the disk to the memory by the operating system. This process is called dynamic linking.

5. Recognition of library name : For example: libc.so, just remove the prefix lib and suffix .so

6. The essence of linking: linking .lib files and .o files

2. Advantages and disadvantages of dynamic and static libraries

The following uses dynamic linking and static linking to generate executable programs respectively (note that -static is required when using gcc for static linking)

1. Dynamic link:

First write the Makefile:

  1 mytest:test.c
  2   gcc -o $@ $^
  3 .PHONY:clean
  4 clean:
  5   rm -f mytest                                                                                                                                  
~

Corresponding test.c code:

  1 #include<stdio.h>
  2 int main()
  3 {
  4   printf("hello ksy\n");                                                                                                                        
  5   return 0;
  6 }

2. Static linking:

Corresponding Makefile:

mytest_static:test.c
  2   gcc -o $@ $^ -static                                                                                                                          
  3 .PHONY:clean
  4 clean:
  5   rm -f mytest

The test.c code is the same as dynamic linking:

If an error is reported when executing the command, you can execute the following two commands:

1.

sudo yum install glibc-static

2.

sudo yum install glibc-static libstdc++-static

 Below we can observe the size of the executable files generated by these two methods:

 We can find that the size of the executable program file generated by static linking is about 100 times that of dynamic linking. much larger

Similarly, we can use the file command to view the file attributes of mytest, mytest_static:

 Use ldd to view the library of the executable program depending on the lazy (note that the executable program generated by dynamic link has only the dependent library, and the executable program generated by static link has no dependent library. The static link will copy the code of the library file to the executable program. in the executable file.

 Finally to sum up:

Advantages of static libraries:

1) When publishing the program, there is no need to provide the corresponding library, because the library has been packaged into the executable file.
2) The loading speed of the library is faster because the library has been packaged into the executable file.
Disadvantages of static libraries:

1) The library is packaged into the application (the final executable file), if there are many libraries, the application will be very large.
2) The library has changed, and the program needs to be recompiled. If there are many source codes, it may take a day to compile it again.

1. Advantages of dynamic libraries

1) The size of the executable program is small: the program loads the dynamic library during execution, and is not packaged with the executable program.
2) The dynamic library is updated, and there is no need to recompile the program (not absolute, provided that the interface of the function is not Change, the content will be fine)
2. Disadvantages of dynamic library

When the program is released, the dynamic library needs to be provided to the user The
dynamic library is not packaged into the application, and the loading speed is relatively slow

3. Packaging and use of static libraries

1. First, let's recall the compilation process: gcc compilation can be roughly divided into four processes

  • gcc preprocessor: put .c文件compiled 预处理into.i文件
  • gcc compiler: compiled into 预处理an assembly file.i文件.s
  • gcc assembler: .scompiled 汇编文件into.o二进制文件
  • gcc linker: link to .oan 二进制文件executable

The commands corresponding to the four stages are as follows: Here is an example of hello.c:

  • Preprocessing:gcc -E hello.c -o hello.i
  • Compile:gcc -S hello.i -o hello.s
  • compilation:gcc -c hello.s -o hello.o
  • Link:gcc hello.o -o hello

The functions corresponding to the four stages:

Preprocessing: (1) Expand the header file in the .c file and add it to the beginning of the .i preprocessing file; (2) Then add the .c file code to the content of the .i header file; (3) Define the macro The magnitude of the value is replaced with a specific value, and the comments in the original code are removed.

Compilation: The translation of c files into assembly files is the conversion of two program syntaxes.

Assembly: Program the assembly file into a binary file, and the specific content of the file at this time cannot be seen.

Linking: Combine the corresponding code in the function library into the object file.

 2. Static library packaging

The essence of static library packaging is to compile the code we wrote into .o to form a binary file without executing the subsequent process, and then package the formed file. Here's the production process:

First, the production of static library

1. Naming rules

1) lib + name of library + .a
2) For example: libmyMath.a


2. Production steps:

1) Generate the corresponding .o binary file .c --> .o eg: gcc sum.c -c sum.o
2) Package the generated .o file using ar rcs + the name of the static library (libMytest.a) + Generated all .o
3) Publish and use static library:
1. Publish static library
2. Header file
Description:

After converting the .c file, that is, the source code into a .o binary file, the customer will not know how your core technology is implemented.
ar is to package .o binary files, rc is a packaging parameter, and all .o binary files are packaged into a .a file, that is: a static library. So: a static library is a collection of packaged binaries. The interface API is reflected in the header file.

The following is a small example to demonstrate the following package of static libraries: To demonstrate this process, I created mypow.c , myadd.c , mypow.h, myadd.h

The following shows the contents of these files:

myadd.h

  1 #ifndef __MYADD_H__
  2 #define __MYADD_H__ 
  3 int add(int x,int y);                                                                                                                           
  4 #endif 

myadd.c

  1 #include"myadd.h"  
  2 int myadd(int x,int y)  
  3 {  
  4   return x+y;                                                                                                                                   
  5 }  
~       

mypow.h

  1 #ifndef __MYPOW_H__
  2 #define __MYPOW_H__ 
  3   int mypow(int x,int y);                                                                                                                         
  4 #endif 
~                 

mypow.c

    1 #include"mypow.h"
W>  2 int mypow(int x,int y)
    3 {
W>  4     if(y==0)
    5     return 1;
    6     if(y==1)
    7     return x;
    8     
    9     return x*mypow(x,y-1);                                                                                                                    
   10 }

Let's introduce the instructions for generating static libraries:

The ar tool packs the formed .o file (with the -rc option when packing) where r and c are replace and creat respectively. Here we set the library name to myMath.

Write Makefile below:

  1 libmyMath.a:myadd.o mypow.o
  2   ar -rc $@ $^
  3 myadd.o:myadd.c
  4   gcc -c $<
  5 mypow.o:mypow.c
  6   gcc -c $<
  7 #清除
  8 .PHONY:clean
  9 clean:
 10   rm -rf output *.o *.a
 11 #发表
 12 .PHONY:output
 13 output:                                                                                                                                         
 14   mkdir -p mylib/include
 15   mkdir -p mylib/lib 
 16   cp *.h mylib/include
 17   cp *.a mylib/lib
~
~

illustrate:

  • include folder: store header files, provided to users to call接口API
  • lib folder: store library files, namely: generated static library, dynamic library
  • src folder: store source files
  • test.c program: the user calls head.h头文件the interface inside, and then calls the algorithm we implement in the static library (but it is not the source code, but compiled into a binary file)

Below we execute make and make out respectively. make out for release.

 Now we have successfully packaged. Now we can give it to others to use.

Let's put this packaged static library into a directory for testing:

Corresponding test test.c content:

    1 #include<stdio.h>
E>  2 #include"mypow.h"
    3 int main()
    4 {
E>  5   printf("%d\n",mypow(2,5));                                                                                                                  
    6 
    7 }
                 

Corresponding makefile:

  1 mytest:test.c
  2   gcc -o $@ $^
  3 .PHONY:clean 
  4 clean:
  5   rm -f mytest         

 We found out what went wrong. When we use gcc to use static linking, we need to tell the compiler the path of the library file, the path of the header file, and the library you want to link and the options corresponding to these three operations are:

Parameter Description:

  • -IParameter: Specify the name of the folder where the header is located. The folder name can be written together with the parameter
  • -LParameters: Specify the folder name of the static library
  • -lParameter: Specify the name of the static library, but the name must be 掐头去尾, eg: the original static library name is libmyMath.a, when specifying -lthe parameter value:-l myMath

Let's modify the Makefile

  1 path =$(shell pwd)
  2 
  3 mytest:test.c
  4   gcc -o $@ $^ -I $(path)/mylib/include -L $(path)/mylib/lib -l myMath -static                                                                  
  5 .PHONY:clean
  6 clean:
  7   rm -f mytest 
~

Here we use path to get the path using absolute path.

Next we compile the program and run it:

 Packaging and use of four dynamic libraries

1. Description of dynamic library

1. Naming rules:

1) lib + name + .so
2) For example: libmyMath.so


2. Production steps:

1) Generate position-independent code (generate position-independent .o)
2) Package .o into a shared library (dynamic library)
3) Publish and use shared library:
Note: The .o file generated by the static library is the same as the location For generating and position-independent .o files with gcc, you need to use the parameter -fPIC (commonly used) or -fpic


2. Examples of dynamic library production

 

To understand what it means to generate a location-independent .o file, we need to contact the virtual address space we learned earlier:

运行的程序Open one ( ) on linux 进程, and the operating system will allocate one (for 32-bit operating systems) 0-4G的地址空间( 虚拟地址空间), 虚拟地址空间not from the virtual address space 内存中。generated by the static library , and the generated binary file will be placed . Generated because is used . The dynamic library/shared library generated by the dynamic library will not be packaged into the program when the program is packaged . It is only done , and then the dynamic library is loaded into the program, that is, it is loaded into the space in the above figure, but each time times loaded into the space . Or make the same directory structure as the static library above:位置有关二进制文件(.o文件)0开始(.o文件)代码段.text代码区.o代码每次都被放到同一个位置绝对地址位置无关二进制文件(.o文件).o文件可执行文件一个记录程序运行之后共享库共享库位置可能不同

In the same way, we still use the above header files for reuse. Let's take a look at the Makfile:

  1 libmyMath.so:myadd.o mypow.o
  2   gcc -shared -o $@ $^
  3 myadd.o:myadd.c
  4   gcc -fPIC -c $<
  5 mypow.o:mypow.c
  6   gcc -fPIC -c $<                                                                                                                               
  7 #清除
  8 .PHONY:clean
  9 clean:
 10   rm -rf output *.o *.so 
 11 #发表
 12 .PHONY:output
 13 output:
 14   mkdir -p mylib/include
 15   mkdir -p mylib/lib 
 16   cp *.h mylib/include
 17   cp *.so mylib/lib

Parameter Description:

1.-PIC: Generate .o files that are independent of location
2.-shared: Shared, that is, to package .o files into dynamic libraries/shared libraries
3. The production of dynamic libraries has been completed above, and then the following two The file can be called after the file is published to the user

4.include/head.h: header file, which defines the interface API
5.lib/libmyMath.so: dynamic library, which encapsulates the compiled source code binary file

Similarly, we put mylib under the test file for testing:

But since this is a dynamic link, we not only have to let the compiler know where the path is, but also let the system know where it is, so we need to import the environment variable LD_LIBRARY_PATH;

 export LD_LIBRARY_PATH=/home/ksy/BK/Test/mylib/lib/. After that we can use:

 

Guess you like

Origin blog.csdn.net/qq_56999918/article/details/124180384