Linux dynamic and static library

Table of contents

1. Understand dynamic and static libraries

1.1 Features of static libraries

1.2 Features of dynamic library 

2. Packaging and use of static libraries

2.1 Packaging of static libraries

2.2 Use of static libraries

3. Packaging and use of dynamic libraries

3.1 Packaging of dynamic library

3.2 Use of dynamic library


1. Understand dynamic and static libraries

A bunch of source files and header files finally become an executable program needs to go through the following four steps:

  1. Preprocessing: Complete header file expansion, comment removal, macro replacement, conditional compilation, etc., and finally form xxx.i file
  2. Compilation: Complete lexical analysis, syntax analysis, semantic analysis, symbol summary, etc., and translate the code into assembly instructions after checking, and finally form the xxx.s file
  3. Assembly: Convert assembly instructions into binary instructions, and finally form xxx.o files
  4. Link: link the generated xxx.o files to finally form an executable program

In fact, all libraries are essentially a collection of object files (xxx.o). The library files do not contain the main function but only contain a large number of methods for calling. It can be considered that the essence of the dynamic and static library is an executable program." Semi-finished products"

  • In Linux .so, the suffix is ​​a dynamic library, .aand the suffix is ​​a static library
  • In Windows .dll, the suffix is ​​a dynamic library, .liband the suffix is ​​a static library

Let's take a look at the dynamic and static library through a simple code

#include <stdio.h>
int main()                                                                                                                                                                       
{
    printf("hello lib\n");//printf()为库函数
    return 0;
}

 Through the ldd command, you can view the library files that the executable program depends on

It can be seen from the above figure that the test executable program depends on  /lib64/libc.so.6 , but it is a soft link, and the linked source file is /lib64/libc-2.17.so . This libc-2.17.so is actually a C dynamic library, remove a library prefix lib, and then remove the suffix, and the rest is the name of the library.

However, gcc/g++ performs dynamic linking by default. If you want to use static linking, you need to add the -static option, and the executable program generated by static linking does not depend on other library files.

And the size of the executable program using the static library is significantly larger than the size of the executable program using the dynamic library

1.1 Features of static libraries

A static library is a program that copies the code of the library into an executable file when compiling and linking. The generated executable program will no longer need a static library when it is running. Therefore, the size of an executable program generated using a static library is generally relatively small. big

  • Advantages: After using the static library to generate an executable program, the executable program can run independently without relying on the library
  • Disadvantages: Using static libraries to generate executable programs will take up a lot of space, especially when multiple static programs are loaded at the same time and these static programs use the same library, then there will be a lot of duplicate code in memory

1.2 Features of dynamic library 

The dynamic library is to link the corresponding dynamic library code when the program is running. It is not necessary to copy the code of the library to the executable file, so that the size of the executable program is smaller than that of the static library, saving disk space. An executable file linked with a dynamic library only contains a table of the entry addresses of the functions it uses, rather than the entire machine code of the object file where the external function is located.

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. The operating system adopts the virtual memory mechanism so that a dynamic library in the physical memory is shared by all processes that want to use the library, saving memory space.

  • Advantages: Save memory and disk space. When multiple programs that use the same dynamic library are running at the same time, the library files will be shared through the process address space, and there will be no duplicate code in the memory.
  • Disadvantage: must rely on dynamic library, otherwise it cannot run

2. Packaging and use of static libraries

In the following demonstration, these files are used as examples. Source files main.c, test1.c and test2.c, header files test1.h and test2.h

main.c file

#include "test1.h"
#include "test2.h"
int main()
{
    test1();
    test2();                                                                                                                                                                     
    return 0;
}

test1.c file

#include "test1.h"                                                                                                                                                               
void test1(){
    printf("This is test1!!!\n");
}

test1.h file

#pragma once
#include <stdio.h>
void test1();            

test2.c file

#include "test2.h"
void test2(){
    printf("This is test2!!!\n");                                                                                                                                                
}

test2.h file

#pragma once                                                                                                                                                                     
#include <stdio.h>
void test2();

2.1 Packaging of static libraries

The first step: Generate the corresponding target file from the source file to be packaged

test1.o:test1.c
    gcc -c tets1.c -o test1.o
test2.o:test2.c
    gcc -c test2.c -o test2.o

Step 2: Use the ar command to package all object files as a static library

The ar command is an archive tool for gnu. The following uses arthe command -rand -coptions to package

  • -r (replace): If the target file in the static library file is updated, replace the old target file with the new target file
  • (create): Create a static library file
libtest.a:test1.o test2.o
    ar -rc libtest.a test1.o test2.o

In addition, we can use the -t and -v options of the ar command to view the files in the static library.

  • -t: list the files in the static library
  • -v(verbose): Display detailed information

Step 3: Organize header files and generated static libraries

mkdir -p my_lib/include
mkdir -p my_lib/lib
cp ./*.h ./my_lib/include 
cp ./*.a ./my_lib/lib

When you want to publish the library for others to use, just publish this folder

makefile full version

libtest.a:test1.o test2.o
    ar -rc $@ $^
test1.o:test1.c
    gcc -c $^ -o $@
test2.o:test2.c
    gcc -c $^ -o $@

.PHONY:output
output:
    mkdir -p my_lib/include
    mkdir -p my_lib/lib
    cp ./*.h ./my_lib/include 
    cp ./*.a ./my_lib/lib

.PHONY:clean
clean:
    rm -rf ./my_lib ./*.o ./*.a           

2.2 Use of static libraries

Option 1: Use options

  • -I: Specify the header file search path
  • -L: Specify the library file search path
  • -l: Indicate which specific library under the library file path needs to be linked

Solution 2: Copy the header files and library files to the system path

[bjy@VM-8-2-centos usedir]$ sudo cp output/include/* /usr/include/
[bjy@VM-8-2-centos usedir]$ sudo cp output/lib/libtest.a /lib64/

Note: Although the header files and library files have been copied to the system path, when using gcc to generate an executable program, it is necessary to specify which library to link

In fact, the process of copying the header files and library files to the system path is the process of installing the library. However, it is not recommended to copy the header files and library files written by individuals to the system path, which will pollute the system files.

3. Packaging and use of dynamic libraries

3.1 Packaging of dynamic library

The first step: Generate the corresponding target file from the source file to be packaged

At this time, you need to add the -fPIC option, that is, generate position-independent code

test1.o:test1.c
    gcc -fPIC -c test1.c -o test1.o
test2.o:test2.c
    gcc -fPIC -c test2.c -o test2.o

-fPIC acts on the compilation stage and tells the compiler to generate position-independent code. At this time, there is no absolute address in the generated code, and all use relative addresses, so that the code can be loaded by the loader to any location in the memory and can be executed correctly. (Establish a mapping relationship with the shared area through the page table). So when the shared library is loaded, its location in memory is not fixed.

Step 2: Use the -shared option to package all object files as dynamic libraries

libtest.so:test1.o test2.o
    gcc -shared $^ -o $@

Step 3: Organize header files and generated dynamic libraries

mkdir -p my_lib/include
mkdir -p my_lib/lib
cp ./*.h ./my_lib/include 
cp ./*.so ./my_lib/lib        

makefile full version

libtest.so:test1.o test2.o
    gcc -shared $^ -o $@
test1.o:test1.c
    gcc -fPIC -c test1.c -o test1.o
test2.o:test2.c
    gcc -fPIC -c test2.c -o test2.o

.PHONY:output
output:
    mkdir -p my_lib/include
    mkdir -p my_lib/lib
    cp ./*.h ./my_lib/include 
    cp ./*.so ./my_lib/lib                                                                                                                                                       

.PHONY:clean
clean:
    rm -rf *.so *.o my_lib

3.2 Use of dynamic library

Next, use the same method as the static library, use -Ithe option to specify the header file search path, use -Lthe option to specify the library file search path, and finally use -lthe option to specify the name of the library. But it can be found that the executable program does not seem to be able to find the location of this dynamic library.

Because the above three options are passed to the gcc compiler, but after the executable program is generated, it has nothing to do with the compiler, so when the program runs, the operating system cannot find the dependent dynamic library.

Solution 1: Copy the .so file to the system shared library path

[bjy@VM-8-2-centos uselib]$ sudo cp ./my_lib/lib/libtest.so /lib64

Solution Two: Change LD_LIBRARY_PATH

LD_LIBRARY_PATHIt is the path to be searched when the program runs to dynamically find the library, just add the directory path LD_LIBRARY_PATHwhere the dynamic library is located to the environment variable.

But this solution can only solve the problem temporarily. When the terminal is closed and then reopened, the imported environment variables will be lost.

Solution 3: Configure /ect/ld.so.conf.d/

All the configuration files with the suffix .conf are stored under the /etc/ld.so.conf.d/ path, and all the configuration files are stored in the path, and the system will automatically store them in /etc/ld.so.conf. Find the paths in all configuration files under the d/ path, and then find the libraries required by the user under each path. If the path of the third-party library file is also placed in this path, then when the executable program runs, the system can find the third-party library file.

First save the path of the directory where the library file is located in a file with a suffix of .conf, then copy the file to the /etc/ld.so.conf.d/directory, and finally use the ldconfig command to update the configuration.

Guess you like

Origin blog.csdn.net/GG_Bruse/article/details/128810497