[Linux] Static library and dynamic library

foreword

For C/C++ learners, we often hear C/C++ standard libraries, and we often use them, but we often only include header files when we use them, and then use them. We have never seriously studied them The C/C++ standard library, and the C/C++ header file only has declarations and no specific implementation of the declared content. Why can we use the library only by including the header files? In this article, let's discuss it together.

1. What is a library

To put it simply: Libraries are retargetable binary files that can be linked with other retargetable binary files to form executable programs when linking.

Generally speaking, libraries are divided into static libraries and dynamic libraries , and they have different suffixes to distinguish them.

System platform static library dynamic library
Windows .lib .dll
Linux .a .so

In addition, for C/C++, the name of the library also has standard requirements, such as Linuxthe following : the general requirement is lib + 库的真实名称 +(版本号)+ .so /.a + (版本号)that the version number can be omitted.

For example, these two standard libraries:
libstdc++.so.6 real name is c++
libc-2.17.so real name is c

The relationship between header files and libraries

  1. The header file provides the method description, and the library provides the implementation of the method. There is a corresponding relationship between the header and the library, and they are to be used together
  2. The header file is introduced in the preprocessing stage, and the essence of the link when the program is linked is actually the link library!

With the above basic knowledge, we can go to see the library. LinuxThe system has pre-installed C&C++ header files and library files for us during installation.

For C/C++ header files, our header files are Linuxgenerally stored under the directory/usr/include

insert image description here

For C/C++ library files, it is generally in /usr/lib64and /lib64inside , /lib64 provides library files such as so or a required by root and the kernel, and /usr/lib64 can be used by ordinary users.

insert image description here

insert image description here

Here we can also understand some phenomena:

  1. When we use a compiler like vs2019, we need to download and install the development environment. What is being downloaded?

    The answer is: install the compiler software, and install the libraries and header files for the language to be developed.

  2. When we use the compiler, there will be an automatic syntax reminder function, but we need to include the header file first, why then?

    The answer is: Grammar reminder is essentially a compiler or editor, which will automatically search the content entered by the user in the included header files. The automatic reminder function depends on the header files!

  3. When we write code, how does our environment know where there are syntax errors in our code and where there are problems defining variables? The answer is: don’t

    underestimate the compiler, the compiler has a command line mode, and others In the automated mode, the editor or the integrated development environment can continuously help us call the compiler to check the syntax in the background without generating an executable file, so as to achieve the effect of syntax checking.

2. How to make a library

The use of libraries can improve our development efficiency, so let's make a library!

1. Static library

Static library: The program links the code of the library into the executable file when compiling and linking. When the program is running, the static library will no longer be needed. Of course, this will also cause the executable program we compile to become larger.

Take a look at the following piece of code to demonstrate the library:

head File:
insert image description here

Source File:

insert image description here

Main program:

insert image description here

File directory structure:

insert image description here

It can be seen that we put the header file and implementation file of the library in mylibthe folder, and main.cput in otherPersonit. At this time, mian.cit is not with the header file and implementation file of the library, and an error will be reported when compiling.

insert image description here

It reminds us that we cannot find the header file. Even if we move the header file, there will be a link error. If we don’t want to give the source code otherPerson, but we want main.c to be able to compile and form an executable program, we need to edit our library The implementation of the file is compiled but does not produce the final executable program.

insert image description here

Then we copy our header files and redirectable binary files into otherPersonit
and then compile and link, and we form an executable programtest

insert image description here

Run test, the program executes successfully

insert image description here

The whole process above is the basic process for us to make a static library. Of course, this kind of production is still flawed. When our project file is too large, we have to give a file more than a dozen such files, and the files are too .cscattered .o. It is not conducive to management, so we need to pack multiple such .ofiles into a package. We give this package directly to others, and they can use it directly.

The packaged command is: ar -rccommand

arCommands are used to create or modify backup files, or to extract files from backup files. Many files can be combined to form a single backup file. In the backup file, all member files retain their original attributes and permissions.

r: If therexxx.a is no module in the packaged library, then the module will be added to the end of the library, and if there is, it will be replaced (the location is still the original location). : Create a backup file.xxx.oxxx.o

c

So we try to package the original .ofiles, but it should be noted that the packaged library must follow the naming convention of the library.

insert image description here

At this point, there is a static library in our current directory. When we delete the static library, the executable program we generated with the static library can still run normally. This is the characteristic of the static library! ! !

2. The use of static libraries

specify the path

When we actually use the library, we usually put the header file in one directory and the library in another file, which is convenient for us to classify and manage. We also follow this standardized approach to organize our directory structure.

insert image description here

Our libmymath.astatic library is not a standard library of C, so gccwe will not link the static library we wrote ourselves when compiling, so we need to add gccsome parameters to indicate the static library we want to link.

insert image description here

(Among them -I - L -l, the content passed after it can be divided by adding spaces or not adding spaces)

-I: Indicate the header file path we want to include
-L: Indicate the path of the library we include
-l: Indicate the library file name we want to include (the library file name here refers to the real name)

./testRun our program and find that the program can start normally.

insert image description here

into the system's default search path

LinuxThe default search path for the C/C++ header file system is: /usr/include. The default search path
for the library file system of C/C++ is: and .Linux/usr/lib64/lib64

We move the file to the corresponding default search path:
insert image description here

At this point we compile ourmian.c
insert image description here

At this time, gccthe compiler reports a link error, reminding us that the library cannot be found. At this time, because we are using a third-party library, we must specify the file name when compiling!

insert image description here
After specifying the path, we can compile normally!

Summary: Use of third-party libraries

  1. Need to specify the header file, and library file
  2. If it is not installed in the system by default gccand g++under the default search path, the user must specify the corresponding option to inform the compiler: a. where is the header file b. where is the library file c. who is the library file
  3. Copy the library and header files we downloaded to the default path of the system, Linuxwhich installation library! So what about uninstallation? For any software, the essence of installation and uninstallation is to copy it to the system-specific path!
  4. If the library we installed is a third-party library, we must use it normally, even if it has been installed in the system, gcc g++we must -lspecify the name of the specific library!

3. Dynamic library

Dynamic library : The code of the dynamic library is only linked when the program is running, and multiple programs share the code of the library. If we delete the dynamic library, the executable programs generated using the dynamic library will not be able to run!

We no longer need arcommands when we make a dynamic library, we need the following two steps:

  1. Add parameters when gccforming binary files -fPIC, so that the resulting redirectable binary files will form position-independent codes.
  2. Then gccadd -sharedparameters to package all retargetable binary files with position-independent codes to form a dynamic library.

Let's take a look at our directory structure:

insert image description here
Form a position-independent code:

insert image description here

Mark as a dynamic library:
insert image description here

When we have a dynamic library, we can delete the redirectable binary file, but the dynamic library cannot be deleted. If the dynamic library is deleted, the programs that depend on this dynamic library will not be able to run!

Next, we try to use the dynamic library to link to form an executable program:

insert image description here

Note: The library we wrote ourselves is a third-party library. When we want to compile, we must specify: header file path, library file path, library file name (real name).

insert image description here

4. The use of dynamic libraries

You can see that we have successfully compiled using the dynamic library, let's run our program.

insert image description here
An error has occurred, and the system prompts us that there is no way to find the dynamic library when the program is running. Why?

This is related to the characteristics of the dynamic library. Since the program using the dynamic library only links the code of the dynamic library when it is running, multiple programs share the code of the library, so the running program must know where to link our library. , that is, for the dynamic library, we need to tell the compiler where to link the library to compile during compilation, and to tell the operating system where to link the library to run during operation.

The static library does not need to be linked because: the binary code used by the user is directly copied to the target executable program during the compilation and linking of the static library. The compiled program is a complete program, and there is no need to use the static library at runtime.

There are three ways to solve the problem that the operating system cannot find the dynamic library:

environment variable

LinuxThere is an environment variable under us LD_LIBRARY_PATH: , the operating system will go to the path under this environment variable to search for dynamic libraries, we can add our third-party libraries to this environment variable, and then we can run our executable program It worked.

insert image description here
Execute our program:

insert image description here
The program executed successfully!

But we all know that environment variables are only valid within one login. If we use the environment variable method, we will still not be able to run the next time we log in, so this method is temporary.

soft link

We know that Linuxthe default library path of C/C++ in Chinese is /usr/lib64or /lib64, which is also the default path for the system to search for libraries. We can create a soft link for our third-party library under this directory (it is not recommended to directly copy the third-party library to the default library path /usr/lib64or /lib64below), so that we can also use it normally.

insert image description here

Execute our program, run normally, soft link a better way to find the library directory.

insert image description here

Modify the configuration file

LinuxThere is a configuration file directory in our /etc/ld.so.conf.dsystem. In this directory, we can create a file and write the path of the dynamic library in the file, so that our system will also search for the path when searching for the dynamic library.

insert image description here
Create the file and fill in our paths:
insert image description here

In this way, we have finished modifying the configuration file, but we still need to make the configuration file take effect immediately, we can use ldconfigthe command.

insert image description here

Once everything is ready we can run our program!

insert image description here

3. Loading of dynamic and static libraries

1. Loading of static library

During the linking of the executable program, the code in the static library will be directly copied into the executable program. Therefore, the static library can be understood as not being loaded during the running of the program, or the static library is loaded together with the program.

However, because it is a static library, when multiple processes contain the same static library, it will cause a lot of duplicate code in the memory, resulting in a waste of memory resources.

2. Loading of dynamic library

When a program using a dynamic library uses a method in the library, a mark will be left at the place of use. When the program is dynamically linked after running, this mark will be replaced with the address in the dynamic library.

When a process A that uses a dynamic library runs and needs a dynamic library a, the operating system will first search for a in the memory, whether it exists, and if it exists, directly map a into the process address of process A through the page table In the shared area in the space, if it does not exist, the dynamic library a in the disk will be loaded into the memory, and then mapped through the page table.

We know that the compiled program has an address inside! The address inside the dynamic library is not an absolute address, but an offset! (relative address)

Because different processes have different levels of operation, the third library that needs to be used is destined to be different, and the free position in the shared space of each process is also uncertain! If absolute addressing is used, address conflicts may occur when a process uses multiple libraries!

When a dynamic library is actually mapped into the address space, its starting address can be truly determined! At this time, the address of the method in the dynamic library is equal to the address of the library plus its own offset in the library. Through this design method, the dynamic library can be loaded at will in the address space of the process, we can all find the methods in the library, and it will not conflict with other libraries! This is position-independent code .

4. Some other conclusions

  1. Dynamic library and static library exist at the same time, and the system uses dynamic link by default
  2. Generally speaking, when an executable program is generated, it will link multiple libraries. We can use lddcommands to check which libraries our program is linked to. The executable program can also choose to use some dynamic libraries and some static libraries when connecting.
  3. If we gccadd -staticparameters to it, gccit will help us link the library by static linking by default.

Guess you like

Origin blog.csdn.net/qq_65207641/article/details/130497420