Learn Linux dynamic and static libraries in 10 minutes
In our daily development, there are often some common codes, such as functions, algorithms, etc., timers, etc. You may find that when multiple modules or multiple projects use the same function or algorithm, each They have to rewrite their code every time, which is time-consuming and laborious. It is also possible that a few lines of code are missed due to a momentary negligence. In this way, it takes a lot of effort to debug.
In order to solve the above problems, library technology has emerged. The library is essentially a binary form of executable code, which can be loaded into memory by the operating system for execution. Some common interfaces can be put into the library. If the application program wants to use The interface only needs to include this library when compiling.
Comparison of static libraries and dynamic libraries
There are two kinds of libraries under Linux, static libraries and dynamic libraries. They have
.a
and
.so
as suffixes respectively. When linking, specify the static library file. The compiler will embed the object code of the static library into the executable file, so the size of the executable file Larger, the code of the shared library is loaded into the memory when the program is running, and can be shared by multiple programs. It is only simply referenced during the compilation process, so the code size is smaller.
In addition, the static library embeds the target code into the executable program. Therefore, subsequent library upgrades require recompiling the executable program, while the dynamic library only needs to update the library file and does not need to recompile the executable program. Its upgrade relatively convenient
The following introduces the steps and methods of generating static libraries and dynamic libraries respectively.
static library
The current directory is sotest, bh and b.cpp are located in the sotest/lib directory
// sotest/lib/b.h
#include <stdint.h>
#include <string>
#include <iostream>
using namespace std;
const std::string &UserName();
const std::string &UserPwd();
// sotest/lib/b.cpp
#include "b.h"
std::string g_username = "mytest";
std::string g_userpwd = "654321";
const std::string &UserName()
{
return g_username;
}
const std::string &UserPwd()
{
return g_userpwd;
}
-
1. Compile the source file into a target file and enter the sotest/lib directory. Execute the following compilation command. After the compilation is completed, a
b.o
target file will be generated in the sotest/lib directory.
-
2. Package the target file into a static library file, enter the sotest/lib directory with .a as the file extension, and execute the following command to
b.o
package the target file in the previous step into alibb.a
file,libb.a
which is a static library file
ar
See the instructions below for the commandCommand format:
ar rcs libxxx.a file1.o file2.o
means generating alibxxx.a
static library file namedr - Insert object files into a library
c - Create library file
s - creates an index into the library file
-
3. After using the static library to generate the static library, use the following test code to test
// sotest/btest.cpp
#include "lib/b.h"
int main(int argc, const char *argv[])
{
cout << UserName() << ", "<< UserPwd() << endl;
return 0;
}
Use the following command to compile the code. After successful compilation, execute ./mytest. The results are as follows
dynamic library
Let’s take bh and b.cpp and sotest/btest.cpp in the sotest/lib directory above as examples to illustrate the generation and use of dynamic libraries.
-
1. Compile source files into dynamic libraries
Enter the sotest/lib directory and execute the following compilation command. After the compilation is completed, a libb.so dynamic library file will be generated in the sotest/lib directory.
Compilation instructions: -fPIC tells the compiler to generate position-independent code, that is to say, there are no absolute addresses in the generated code, all relative addresses are used, so the code can be loaded into any location in the memory and can be executed correctly. This is very important and is also required by the dynamic library
-
2. Use dynamic libraries
Or use the above test code, enter the sotest directory, use the following command to compile and run, the results are as follows
Command description: -L means specifying the path of the dynamic library. If not specified, it means using the system default search path (usually /lib or /usr/lib). -lb means referencing the libb.so library. When quoting, omit the previous lib and .so suffix
We found that after successful compilation, running the executable program directly will report an error: Error loading shared library, there is no such file or directory. This is because the dynamic linker cannot find the dynamic library when loading.
Some students may say that when compiling the above, didn't you use -L to specify the path of the dynamic library? Why is it still prompted that the dynamic library cannot be found when running?
This is actually the difference between compilation linking and running loading. The path specified with -L when compiling above only specifies the library file search path during the compilation and linking phase. It cannot determine the search path for loading library files during runtime. To ensure that the compilation passes , as long as the library file is found in the path specified by -L, it is enough, but the operation is related to the specific running environment, and the search path of the runtime library cannot be determined at compile time.
Therefore, when running, it prompts that libb.so is not found. Generally, there are several reasons:
1. The libb.so library file itself does not exist. You need to ensure that the library file has been generated.
2. The library file exists, but is not in the default search path. You need to add the path of the library file to the environment variable LD_LIBRARY_PATH, or copy the library to the standard path /lib or /usr/lib.
3. Library files depend on other library files. You need to ensure that all dependent library paths are added recursively.
4. The library file exists and the path is correct, but the file names do not match. For example, the library file name is libb.so.1, and the program is looking for libb.so
5. Permission issues prevent library files from being read.
6. The library file version is incompatible, causing reading failure.
After comparing them one by one, we will find that the path to the dynamic library is not set here. There are several ways to set the path:
1. Copy libb.so to /lib or /usr/lib
Execute the cp command to copy the dynamic library to the /lib directory. The specific operation is as shown in the figure below.
It can be seen that after copying libb.so to the /lib directory, and then compiling and running, the output will be normal.
Note: After copying the dynamic library to the /lib or /usr/lib directory, you need to execute the sudo ldconfig command to refresh the /etc/ld.so.cache cache.
2. Add the path to the environment variable LD_LIBRARY_PATH
Execute
export
the command to add the dynamic library path
/home/smb/wl/mytst/sotest/lib/
to the environment variable
LD_LIBRARY_PATH
, and then run it. As you can see from the figure below, the final output is correct.
Note:
The method of
export
importing the library path into the environment variable
LD_LIBRARY_PATH
is only valid for the current SSH connection. When a new SSH connection is opened, it needs to be reset. A better way is to
LD_LIBRARY_PATH
add the environment variable to
~/.bashrc
it, so that it is valid for the current user. , if you add it
/etc/bashrc
to , it will be valid for all users
3. Add the path
/etc/ld.so.conf
to
As shown below, open
/etc/ld.so.config
and write the dynamic library path
Execute
sudo ldconfig
the command to refresh
/etc/ld.so.cache
the cache, and then run the executable program. The result is as shown below
When opening it above
/etc/ld.so.config
, we found that the first line is:
include ld.so.config.d/*.conf
, which means that we can also put the dynamic library path into a custom configuration file, and then copy this configuration file to
/etc/ld.so.conf.d/
the directory. The executable program loads the dynamic When adding a library, it will automatically search in the directory in the custom configuration and write the library directory into the custom configuration
my.conf
.
Copy the custom configuration
my.conf
to
/etc/ld.so.conf.d/
the directory and use
ldconfig
the command to refresh the cache
Finally, run the executable program. It can be seen that the printing is correct.
How to view the dynamic libraries linked to a program
Use
ldd btest_so
the command to view which dynamic libraries are loaded by the executable program and the path of each dynamic library
As shown in the picture above, the part in the red box is the dynamic library written by yourself and the path of the dynamic library. If loading the dynamic library fails,
"not found"
the words will be displayed, as shown below
summary
This article mainly introduces the generation and use of dynamic libraries and static libraries under Linux. Although these are relatively basic knowledge, you still need to practice it yourself to master it proficiently.
Recently, many friends have asked me for some essential information for programmers, so I dug out the treasures at the bottom of the box and shared them with everyone for free!
Scan the QR code of the poster to get it for free.