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 libraryWhen 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:
.s
compiled汇编文件
into.o
二进制文件
- gcc linker: link to
.o
an二进制文件
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:
-I
Parameter: Specify the name of the folder where the header is located. The folder name can be written together with the parameter-L
Parameters: Specify the folder name of the static library-l
Parameter: Specify the name of the static library, but the name must be掐头去尾
, eg: the original static library name islibmyMath.a
, when specifying-l
the 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 user4.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: