Linux静态库和共享库

一、库的基本概念

1、库

Linux下编译生成一个可执行文件时,需要将这个可执行文件需要的函数目标文件包含进去。对于一个较大的工程来说可能有很多的函数目标文件,这些目标文件可能会被其他工程或程序所调用,因此比较好的方法是将这些函数目标文件组合在一个单独的文档文件中,这就是库文件。

2、库的概念

库有两种形式:静态库和共享库
(1)静态库的代码在编译时就已连接到开发人员开发的应用程序中。
(2)共享库只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。


由于共享库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此可执行文件的代码规模比较小。
但是要注意,对于加载了静态库的可执行文件,由于静态库的代码已经连接进入了可执行程序中,所以静态库与可执行文件的路径没有关系了,可执行文件可以放置在任何路径下。而对于加载了共享库的可执行文件,共享库的路径与可执行文件的位置有直接的关系,位置错误可执行文件将无法正常运行。
Linux系统已经开发的大多数库都采取共享库的方式。

3、库的名字

系统中可用的库都存放在/usr/lib和/lib目录中。库文件名由前缀lib和库名以及后缀组成。根据库的类型不同,后缀名也不一样。
(1)静态库的后缀名为.a,如libname.a。
(2)共享库的后缀名由.so版本号组成,如libname.so.5。
这里的name可以是任何字符串,用来唯一标识某个库。该字符串可以是一个单字、几个字符、甚至一个字母。如数学共享库的库名为libm.so.5,这里的标识字符为m,版本号为5。libm.a则是静态数学库。X-Windows库名为libX11.so.6,这里使用X11作为库的标识,版本号为6。C语言的标准函数库名字为libc.so后接版本号。

4、GCC与库

在/usr/lib和lib目录中可以找到绝大多数的共享库。GCC编译器连接时将首先搜索这两个目录。有一些库也可能存放在特定的目录中,在/etc/ld.so.conf配置文件中给出了这些目录的列表。连接程序也会对配置文件中列出的这些目录进行搜索。在默认情况下,Linux将首先搜索指定库的共享版本,如果找不到,才会去搜索静态版本。
如果程序员自己编写了库文件,并打算GCC连接时自动找到该库文件可以怎么做呢?
首先,将该库文件复制进入/usr/lib或/lib中,或者将该库文件的绝对路径加入/etc/ld.so.conf配置文件中。
然后运行ldconfig 命令进行更新。

二、静态库的创建与使用

vim output.c

#include<stdio.h>
void output(char str[]){
     printf("hello,%s\n",str);
}

vim main.c

#include<stdio.h>
void output(char str[]);
int main(){
    char name[]="neusoft";
    output(name);
    return 0;
}

1、静态库的创建

(1)生成目标文件
在这里插入图片描述
(2)生成静态库
在这里插入图片描述
-r选项:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。
-c选项:不论库是否存在都将创建,不给出警告。
s选项:强制更新库的符号表,即使库的内容没有发生变化,显示执行操作选项的附加信息。

2、静态库的使用

方法一
在这里插入图片描述
方法二
在这里插入图片描述
方法三
在这里插入图片描述

三、共享库的创建和使用

1、共享库的创建

(1)生成目标文件
在这里插入图片描述
-fpic选项产生位置独立的代码。由于库是在运行的时候被调入,因此这个选项是必需的,因为在编译的时候,装入内存的地址还不知道。如果不使用这个选项,库文件可能不会正确运行

(2)生成共享库
在这里插入图片描述

2、共享库的使用

方法一
在这里插入图片描述
将共享库libshare.so拷贝到/usr/lib
在这里插入图片描述
方法二
在这里插入图片描述
在这里插入图片描述
查看可执行文件使用的共享库
在这里插入图片描述

### Linux静态库共享库的区别 #### 静态库的特点 静态库是在编译阶段被完全复制到目标二进制文件中的。这意味着每次构建应用程序时,都会将整个静态库的内容嵌入到最终的可执行文件中。这种方式的优点在于生成的应用程序独立性强,在运行时不依赖外部库的存在;缺点则是增加了可执行文件大小,并且如果多个应用都链接同一个静态库,则会浪费磁盘空间。 创建静态库通常涉及两个主要步骤:先编译源码为目标文件(.o),再通过`ar`工具打包成`.a`格式的档案文件[^5]。 ```bash gcc -c foo.c bar.c ar rcs libfoobar.a foo.o bar.o ``` #### 动态库/共享库的特点 相比之下,动态库(也称为共享对象或SO文件)只会在加载时刻按需映射至内存地址空间内。这不仅减少了重复代码占用的空间,还允许不同进程间共享同一份物理副本,从而节省资源开销。此外,更新版本只需替换对应的.so文件即可生效而无需重新编译所有依赖它的软件包。 为了使GCC能够找到所需的动态库位置,可以利用环境变量`LD_LIBRARY_PATH`设置额外路径或者安装到标准目录如/usr/lib下[^4]。 ```bash gcc main.c -L. -lmylib -o app export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH ./app ``` #### 使用上的差异 当开发者希望发布易于分发的小型独立程序时可能会倾向于采用静态链接方式;而对于大型项目尤其是那些追求高效能及模块化的场景则更适于选用动态链接方案。另外值得注意的是某些情况下操作系统本身自带的核心功能是以动态形式提供的因此无法选择静态化处理[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值