C++程序库的依赖关系中需要根据库名和版本确定某个库是否能够实际匹配,那C++的动态库又是怎么记录库名和版本的呢,这篇文章聊一下Linux C++动态库是怎么记录这些信息的。
C++动态库记录自己的库名和版本有一个非常简单的方法,就是文件名,比如一个库文件的文件名是libdemo.so.1.2.1,这个文件名里就描述了库名和版本。
但是这种方式一般只是一种比较直观的表现形式,真正需要记录的话不会只采用这种方法。
我们知道很多文件都需要能够自解释,C++的动态库文件也不例外,在C++动态库文件的内容里有一个SONAME信息,这个SONAME就描述了库名以及版本,C++动态库文件的文件格式叫ELF,这个信息会包含在ELF格式的头部中。这个SONAME信息就是真正记录的方法。
现在我们知道了怎么记录库名和版本,那么这些信息又是怎么来的了,那自然是构建的时候设置的,我们来看一下怎么设置。
以使用cmake为例,看一个简单示例,先看一下结构
然后看下具体代码
// demo.h
#ifndef DEMO_H
#define DEMO_H
class Demo
{
public:
Demo() = default;
~Demo() noexcept = default;
void Func();
};
#endif
// demo.cpp
#include "demo.h"
#include <iostream>
void Demo::Func()
{
std::cout << "demo" << std::endl;
}
很简单的代码,然后重点看下CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(demo)
aux_source_directory(src srcfiles)
add_library(${PROJECT_NAME} SHARED ${srcfiles})
target_include_directories(${PROJECT_NAME} PUBLIC include)
set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION 1.2.1
SOVERSION 1.2
OUTPUT_NAME ${PROJECT_NAME}
)
这个CMakeLists.txt中的指令set_target_properties就是在设置库名和版本,VERSION指定了动态库的完整版本号,SOVERSION指定了在SONAME里记录的版本号,OUTPUT_NAME指定了不包括版本号的动态库基本名称,cmake会自动根据这些信息生成正确的SONAME信息和文件名。
我们执行命令cmake -B build
和cmake --build build
构建一下
可以看到不仅生成了动态库,而且还创建了符号链接。
那我们怎么知道SONAME信息是不是对的呢,可以使用readelf命令查看,比如执行命令readelf -d ./build/libdemo.so
可以看到SONAME正确记录了库名和版本。
C++动态库文件的SONAME信息记录的是自己的库名和版本,NEEDED信息里记录的就是依赖项的库名和版本。
我们看一下怎么查,还以前面我们构建的那个动态库为例,还是使用readelf命令查看动态库的信息
这样就可以看到C++动态库记录在NEEDED信息里的依赖项的库名和版本了。
如果只是想查看依赖了哪些库,另外还有一个命令ldd可以方便的查看C++动态库依赖哪些库,比如执行命令ldd ./build/libdemo.so
这个命令可以列出来直接和间接依赖的所有依赖项,使用比较方便。
如果这篇文章对你有帮助,别忘了关注我啊,可能我还会写出更多对你有帮助的文章
因篇幅问题不能全部显示,请点此查看更多更全内容