Article count:922 Read by:3074353

Account Entry

Learn Linux dynamic and static libraries in 10 minutes

Latest update time:2023-12-25
    Reads:



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 a libb.a file, libb.a which is a static library file

ar See the instructions below for the command

Command format: ar rcs libxxx.a file1.o file2.o means generating a libxxx.a static library file named

r - 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.



Latest articles about

 
EEWorld WeChat Subscription

 
EEWorld WeChat Service Number

 
AutoDevelopers

About Us Customer Service Contact Information Datasheet Sitemap LatestNews

Room 1530, Zhongguancun MOOC Times Building,Block B, 18 Zhongguancun Street, Haidian District,Beijing, China Tel:(010)82350740 Postcode:100190

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号