Linux basic IO (four): the production and use of dynamic and static libraries

1. Basic understanding of dynamic and static libraries

1. Static library

  • Static library .awith file suffix
  • When the program is compiled and linked , the code of the static library is copied to the executable file, so the program will no longer depend on the library file when it runs

2. Dynamic library

  • The dynamic library .soends with the file suffix
  • The code of the dynamic library is only linked when the program is running , and the same library code is shared between multiple programs
  • An executable file linked with a dynamic library only contains a table of the function entry addresses 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 uses a virtual memory mechanism to allow a dynamic library in physical memory to be shared by all processes that use the library, saving memory and disk space. Therefore, the use of dynamic libraries is more extensive

2. The engineer's perspective of the design library

(1) Make a static library

There are three steps to making a static library:

  1. Compile all .cfiles into .oa file .
    image-20221111174044751


  2.  We only provide all the .o files when packaged into a static library . Can others directly link and use it? Yes. Because of the nature of the link, the required .o files are linked. We can manually link all .ofiles :
    image-20221111171121037
     Although we can directly link all .ofiles to generate executable programs, when there are many .o files in the library, it will be cumbersome to use and the entire file will be redundant. So we can use arthe (archive) command to package all .o files into a static library:
    image-20221111174231759
    [Note]: The name of the library is also particular, it needs to be prefixed with lib and suffixed with .a or .so


  3.  What does it take to distribute头文件 a library? And 库文件, so we add it to the /lib folder and the /include folder respectively as our distribution method:
    image-20221111191007019image-20221111191641785

(2) Make a dynamic library

  1. Compile all .cfiles to generate .ofiles
     . Note that -fPICthe option to generate position-independent code, and the relative address scheme is used to determine the location of the dynamic library.
    image-20221111192314989
  2. The option to generate a dynamic library
    - shared is used to specify the generation of a shared libraryimage-20221111193114879
  3. release
    image-20221111192544791image-20221111193234859

2. The user perspective of using the library

As we all know, there are two ways to include header files:

  • include "xxx": look for header files in the current directory
  • include : Look for header files in the system directory

(1) Use a static library

 Including header files is a big problem when using self-implementing libraries. Because the object files we write are often not in the same path as the library files and header files , and the library files and header files are usually stored separately (see release methods), so we cannot directly use the above two methods of including header files. Three solutions are given below:

  1. Copy to the system path
     The header files of the system are stored in /usr/includethe path , and the library files are stored in /lib64the path. The compiler will automatically look for header files and library files in the system path, so we can consider adding header files and library files to the system path. This is essentially installing a third-party library .
    image-20221112092231325But when we tried to use library files and header files again, the following error occurred: image-20221112092457251
     We have to figure out the concept: the path is only used to find where the library is, but there may be many libraries under a certain path at the same time. When we use a third-party library (non-C language standard), the compiler does not know it natively, so we need to actively add -loptions specify the library we want to link when compiling :
    image-20221112093059699[Description]:
  • -lBetween and the following library name, spaces can also be five
  • -lThe specified library name needs to remove libthe prefix and .asuffix, because it will be added automatically when matching. For example, when using a library file libmydate.anamed , it needs to be written as-lmydate

   But it is not recommended to add the library we write daily to the system path, because it may pollute the naming pool of the system directory. Of course, if your level is very high, that's of course no problem.

  1. Specify search paths
    image-20221112101645945
    [description]:
  • -I option: specify the path to look for the header file
  • -L option: Specify the path to find the library file
  • -l option: specify the library to use

(2) Use dynamic library

When we specify the file path to generate an executable program, we encounter the following error message when we try to run it:

image-20221112102330006

Use lddthe command to view the dependencies of the file to find the problem:

image-20221112102427587

​ Why can't .sothe file be found? We have clearly specified the path? Here we need to distinguish a set of concepts:

  • -I -L -lAll are gcc options, only related to gcc
  • After forming an executable program, gcc has nothing to do with the following
  • Programs are run by processes. If no one tells the path of the process library file, the above error message will naturally appear

Here are four solutions:

  1. Add the library file to the system path.
    When the program runs, it will automatically go to /lib64the path to find the corresponding library file.
  2. Import the library file into the environment variable
     When the program runs, it will automatically find the required dynamic library path in LD_LIBRARY_PATHthe environment variable, so we can manually add the path of the library file LD_LIBRARY_PATHto , it is best to add an absolute path, so that it can be used anywhere . (: used to separate different paths)
// 注意不要写成如下的形式,这样就将LD_LIBRARY_PATH的初始数据覆盖了
export LD_LIBRARY_PATH=xxx
  1. Configure system files
    When we restart xshell, we will find that the environment variable information we added before is gone. This is because bash reads data from the configuration file to regenerate environment variables every time it restarts .
     For permanent modification, we can try to modify the system configuration file. In addition to searching for library files in the default path, the operating system will also traverse all configuration files /etc/ld.so.conf.dunder , and find the path where the target library is located according to the content of the configuration files.

    The content of the configuration file is also very simple, which is the path where the library file is located.
    image-20221112112344308

    Then use ldconfigthe command to load the configuration file into memory to make the configuration file take effect.
    image-20221112114453688

  2. Create a soft link of the library file in the system path.
    The soft link is essentially a shortcut , and the link can be canceled by using unlinkthe command
    image-20221112115801052

3. The angle of understanding

[Question 1]: Why does the static library not need to be searched at runtime?

​ Answer: When using a static library to generate an executable program, the code of the library file has been copied to the code area . So no runtime lookup is required.

[Question 2]: Why do dynamic libraries need to be searched at runtime?

​ Answer: Because the program and the dynamic library are loaded separately. (The following explanations require a certain understanding of the process address space) When we load the program into the memory, the OS creates a process control block PCB

for our program and establishes the process address space . Because our code uses a dynamic library, some code needs to jump to the dynamic library for execution.

​ To jump to a dynamic library, the premise is to load the dynamic library into memory . Since it is to be loaded into memory, the dynamic library must be found. After the dynamic library is loaded into the memory, the dynamic library in the memory is mapped to the area between the stacks through the page table共享区 , and this area is called .

​ Our code is stored in the code area. When the code in the dynamic library needs to be executed, just jump to the shared area. After execution, jump back to the code area and continue to execute. From this we can execute all the code (our own and the dynamic library) in our own address space.

​ In the entire memory, although there is only one copy of the dynamic library, the dynamic library can be shared by multiple processes through the process address space, so the memory space can be greatly saved.

Guess you like

Origin blog.csdn.net/whc18858/article/details/127821450