技术分享 | Linux系统中的库

本文详细介绍了Linux系统中的库概念,包括静态库和动态库的区别。静态库在编译时链接,体积大但移植方便;动态库在运行时链接,节省空间但需要运行环境。创建和使用静态库、动态库的步骤也进行了阐述,强调了动态库的路径和链接问题。此外,还提到了如何通过apt安装缺失的动态库以及解决运行时找不到库的问题。
摘要由CSDN通过智能技术生成

大家好,我是阿木实验室的松溪,今天给大家介绍一下,Linux系统中,库的概念。

一、库的简介

什么是库,库简单地说,就是模块。用于提供不同功能的模块,比如我们经常会用的ceres库,eigen库,pcl库等等。库从本质上来说,是一种可以执行代码的二进制形式,可以被载入到内存中使用,在Liunx系统中,库以文件的形式存在,并且可以分为动态链接库和静态链接库两种,简称为动态库和静态库。其中,静态库文件的后缀为.a,动态库文件的后缀为.so。无论是动态库还是静态库,它们无非是向调用的人提供变量、函数或者类。

二、库的区别

静态库和动态库的区别在于:二者代码被载入的时刻不同。静态库在程序编译的时候会被链接到目标代码中,目标程序运行的时候将不再需要该库,移植方便,但是体积会变大,浪费空间和资源,因为与之相关的所有文件都会链接合成一个可执行文件,导致可执行文件的体积变大。动态库在程序编译的时候并不会被链接到目标代码中,而是在程序运行的时候才被载入,因此可执行文件体积较小。

基本上,大部分的库都是动态库,比如:eigen,ceres等,这就是我们通常所说的依赖项,如果你的程序中有需要某个库,而你的环境中没有这样的库,那么在编译的时候就会出现这样的错误:xxxx.h文件未找到。这就是典型的缺少动态库的bug。对此,只需要安装对应的动态库即可解决。这个问题经常出现在当你clone某一个代码下来,但是却没有这个代码的运行环境,当你编译的时候,就会出现上面的报错。是不是又get到了一个小技巧呢?

三、静态库的创建和使用

在Linux系统中创建静态库的过程如下:

  1. 编辑源文件(.c或.cpp文件)

  2. 通过 gcc -c xxx.c 或 g++ -c xxx.cpp 生成目标文件(.o文件)

  3. 使用 ar 命令归档目标文件,生成静态库

  4. 配合静态库写一个头文件,文件里的内容就是提供给调用者使用的函数、变量或者类的声明。

在实际创建之前,有必要了解一下,ar命令的使用。ar命令不但可以创建静态库,也可以修改或提取已有静态库中的信息,其基本用法如下:

ar [option] libxxx.a xx1.o xx2.o xx3.o

其中,libxxx.a是生成静态库的文件名字,xxx是自己设定的名称,lib表示该文件是一个库,所有在Linux下的库,都遵守这种命名。即libxxx.a或者libxxx.so。xx1.o xx2.o为静态库的目标代码文件,可以有多个。option常见的选项如下:

-c:创建一个库,无论库是否存在,都会创建

-s:创建目标文件索引

-r:在库中插入模块,如插入的模块名已经在库中存在,则将会替换。如果有一个模块不存在,将会保存,并不会替换其他同名模块

-t:显示库文件中有哪些目标文件。仅仅显示

-tv:显示库文件有哪些目标文件。包括文件名、时间、大小等

-s:显示静态库文件中的索引表

下面将讲解如何创建和使用一个静态库

新建一个源文件,test.cpp,复制以下代码:

#include

void show_age(int age) { std::cout << "Your age is: " << age << std::endl; } 然后输入命令

g++ -c test.cpp ar rcs libshowage.a test.o 这样就生成了一个静态库,要想使用,需要编写另一个源文件,demo.cpp。复制以下代码

#include

extern void show_age(int age); //声明要使用的函数

int main(int argc, char** argv) { show_age(18); std::cout << "Hi" << std::endl; } CMakeLists.txt文件

cmake_minimum_required(VERSION 3.0) project(demo)

add_executable(demo demo.cpp) target_link_libraries(demo -L.. -lshowage) 其中,-L参数表示从什么地方找这个库,(..)表示上一级目录。-l指定具体的库,其中lib和.a不需要显示写出,编译器会自动去寻找libshowage.a这个文件。这也就是为什么库命名的时候要以lib开头。

四、动态库的创建和使用

在Linux系统中,存放动态库的路径一般为/usr/lib。在Linux系统下进行的链接,默认是先链接动态库,如果同时存在静态库和动态库,如果不特别指出,将与动态库链接。这样有助于节省空间。

同理,我们创建一个动态库,test.cpp。代码同上,不做改变。只需要修改生成动态库的命令。该命令如下:

g++ test.cpp -fPIC -shared -o libshowage.so -shared 表示生成共享库

-fPIC表明使用地址无关代码。PIC全称是Position Independent Code。在Linux系统下编译共享库时,必须加上这个参数,否则在链接的时候将会报错。因为共享库文件可能会被不同的进程加载到不同的位置上,如果共享对象中的指令使用了绝对地址、外部模块地址等,那么该库在被加载的时候,就需要修改地址,这样就不能实现多进程共享一份物理内存。

编写一个调用该库的函数,demo.cpp。内容还是不变。CMakeLists.txt也不变。

五、多个文件生成一个动态库

创建test1.cpp文件,复制以下代码

#include

void show_age_1(int age) { std::cout << "This is lib_1: " << age << std::endl; } 创建test2.cpp文件,复制以下代码

#include

void show_age_2(int age) { std::cout << "This is lib_2: " << age << std::endl; } 创建动态库

g++ test1.cpp test2.cpp -fPIC -shared -o libshowage.so 需要说明的是,多个文件创建动态库的时候,不能有同名的函数、类、变量的声明,否则将无法创建,因为就算创建成功以后,当调用的时候,编译器并不知道该去调用哪一个源文件里面的声明。

创建 main.cpp 文件,使用这个库,复制以下代码

#include

//声明要使用的函数 extern void show_age_1(int age); extern void show_age_2(int age);

int main(int argc, char** argv) { show_age_1(18); show_age_2(36); } CMakeLists.txt文件如下

cmake_minimum_required(VERSION 3.0) project(demo)

add_executable(main main.cpp) target_link_libraries(main -L.. -lshowage) 当我们运行的时候,会发现这样的错误

./main: error while loading shared libraries: libshowage.so: cannot open shared object file: No such file or directory 在编译的时候,我们告诉了编译器,在什么地方去寻找该库,但是在运行的时候,由于该库是动态库,其代码没有被链接到目标代码中,因此,在运行的时候,会提示找不到该库。

因此,只需要将动态库放到默认的路径上或者告诉其指定路径即可。

在Linux系统中,一般将库放在以下三个地方。其中,/lib用于放置系统级别(或者说内核级别)的库文件,/usr/lib 用于放置程序级别的库文件,/usr/local/lib 为用户级别,一般用户编译的都放在这里,以及源码编译安装,例如:opencv的源码编译。

因此,我们要将自己的库放在 /usr/local/lib 下,输入以下命令

sudo cp ~/C++/demo/libshowage.so /usr/local/lib 当我们移动以后,需要输入以下命令(必须),更新

sudo ldconfig 这样,当我们再次运行的时候,就不会报错了。切记,每次有动态库在上述目录中发生变动,都需要输入这个命令更新,否则还是无法识别。

六、通过apt安装缺少的动态库

当我们从github上clone代码的时候,在编译的时候,经常出现xxx.h文件不存在,或者No such file or directory。其本质上就是你的环境和别人的环境不一致,缺少相应的库。一般的解决方式是,将该缺少的头文件复制到百度,查一查这个头文件是来自哪一个库。然后打开终端,输入命令

sudo apt install libxxx-dev 即可

如果是自定义的动态库,一般在readme文档中有说明。

同理,当你向开源社区贡献开源代码的同时,也请务必告知运行的环境以及所需要的库。

七、总结

相信通过本文的介绍,读者对库有了一个简单的认识,在以后的工作和学习过程中,遇到类似的问题,也有了解决问题的思路和方法。

  • End -

技术发展的日新月异,阿木实验室将紧跟技术的脚步,不断把机器人行业最新的技术和硬件推荐给大家。看到经过我们培训的学员在技术上突飞猛进,是我们培训最大的价值。如果你在机器人行业,就请关注我们的公众号,我们将持续发布机器人行业最有价值的信息和技术。 阿木实验室致力于为机器人研发提供开源软硬件工具和课程服务,让研发更高效!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值