静态库(.a)与动态库(.so)的简明介绍(代码片段)

racaljk racaljk     2022-12-28     720

关键词:

静态库(.a)与动态库(.so)的简明介绍

gcc有很多关于静态库,动态库的选项如-l,-L,-fPIC,-shared -Wl,-soname,看着很复杂容易混淆,其实静态库和动态库都是应需而生,只要有了一个线索都很容易理解。

普通编译

假设有三个文件(后面均使用这个例子):

// mod1.c

#include <stdio.h>

void print_mod1()
    printf("%s
",__func__);    


// mod2.c
#include <stdio.h>

void print_mod2()
    printf("%s
",__func__);      

//main.c
int main()
    print_mod1();
    print_mod2();
    return 0;

我们要想运行这个程序需要先编译mod1.c,mod2.c生成目标文件,然后目标文件与main.c结合完成编译:

$ gcc -c mod1.c mod2.c
$ gcc -o resultant main.c mod1.o mod2.o
$ ./resultant
print_mod1
print_mod2

使用静态库(-lname -Lpath)

如果mod再多一点就会出现体力劳动:

$ gcc -o resultant mod1.o mod2.o mod3.o mod4.o mod5.o ... mod1024.o

于是就引入了静态库的概念。静态库又叫归档文件,在linux下是*.a后缀的文件,本质上就是目标文件(*.o)的一个集合。

  • 使用ar -r命令可以将*.o打包为一个静态库
$ ar r libmod.a mod1.o mod2.o
  • 使用ar tv libmod.a查看归档里面有哪些目标文件:
$ ar tv libmod.a
rw-r--r-- 0/0   1544 Dec 31 16:00 1969 mod1.o
rw-r--r-- 0/0   1544 Dec 31 16:00 1969 mod2.o
  • 使用ar d libmod.a mod2.o删除一个不需要的目标文件

打包好后就可以用libmod.a代替一串目标文件了:

$ gcc -o resultant main.c libmod.a

最常用的链接静态库的方式是添加-lname选项。-lname会默认链接名为libname.a的静态库:

$ gcc -o resultant main.o -lmod
/usr/bin/ld: cannot find -lmod
collect2: error: ld returned 1 exit status

这里我们如果直接使用-lmod gcc会提示找不到libmod.a模块,因为gcc只会在标准路径如/usr/lib,/lib查找,解决方法一是把libmod.a放到标准路径,二是使用-Lpath选项。

$ gcc -o resultant main.c -L. -lmod
$ ./resultant
print_mod1
print_mod2

-Lpath把指定路径加入链接器搜索路径,这里我们把当前目录(.)加入,自然就能找到libmod.a了。

使用动态库(-fPIC -shared)

静态库优点是方便,缺点是每个程序都有一份目标文件的,很多程序会使用printf,如果每个程序都包含一份printf.o的实现,会非常浪费磁盘空间和宝贵内存页。还有如果要对静态库中某一个目标文件进行更新,那么应用程序就需要重新链接。
基于这些需求,动态库诞生了。

动态库需要位置独立的代码,所以不能使用前面的mod1.o,mod2.o,需要-fPIC选项重新编译:

$ gcc -c -fPIC mod1.c mod2.c

然后再组合成动态库:

$ gcc -shared -o libmod.so mod1.o mod2.o

最后使用这个动态库:

$ gcc -o resultant main.c libmod.so
$ ./resultant
./resultant: error while loading shared libraries: libmod.so: cannot open shared object file: No such file or directory

好了,不出所料,又出问题了。gcc提示加载动态库失败,找不到它。动态库的搜索顺序如下

  1. 编译目标代码时指定的动态库搜索路径;
  2. 环境变量LD_LIBRARY_PATH指定动态库搜索路径,它指定程序动态链接库文件搜索路径;export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:data/home/billchen/lib
  3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径;
  4. 默认的动态库搜索路径/lib;
  5. 默认的动态库搜索路径/usr/lib。

这里简单起见,我们直接将libmod.so移动到/lib

$ sudo mv libmod.so /lib
$ ./resultant                      
print_mod1
print_mod2

动态库别名(-Wl,-soname,xx)

这里再说说-Wl,-soname,该选择告知链接器一个动态库的别名

$ gcc -shared -Wl,-soname,libalias.so -o libmod.so mod1.o mod2.o
$ gcc -o resultant main.c libmod.so

上面命令使用libalias.so作为libmod.so的别名,再次运行resultant会提示找不到libalias.so错误而不是libmod.so,-soname别名引入一个中间层,好处是程序运行时可以使用和编译时不一样的兼容库。

gcc编译过程与动态链接库和静态链接库(代码片段)

...二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。windows上对应的是.lib.dlllinux上对应的是.a.so在这里先介绍下Linux下的gcc编译的几个选项g++-chellospeak.cpp会将hellospeak.cpp选项-c用来告诉... 查看详情

linux静态库和动态库编译的区别

Linux库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。例如:libhello.solibhello.a为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如:libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以... 查看详情

动态链接库.so和静态链接库.a(代码片段)

前言个人总结动态链接库静态链接库符号表strip不strip查看符号表1.使用objdump命令。objdump-tTxxx.so2.使用nm命令(个人觉得使用nm方式查看更方便。)nm-Dxxx.so#-D或-dynamic选项表示:显示动态符号。该选项仅对于动态库有意... 查看详情

linux篇第十篇——动静态库(动静态库的介绍+动静态库的打包与使用)(代码片段)

...了基础IO相关的一些内容。这篇博客要继续聊一聊关于动静态库相关的一些内容。在之前的学习过程中,我们也会使用C/C++的相关的库,这些库都是由不同的语言打包好了的,我们直接调用即可。下面我们就会好... 查看详情

静态库,动态库

...进制代码。这个二进制代码可以是动态的,如.so也可以是静态的,如.a,如果是动态的,则你最后生成的程序文件在运行时,需要这个动态库的支持,如果是静态的,则你最后生成的客执行程序文件运行时可以脱离这个库文件而... 查看详情

库的区别

...二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。windows上对应的是.lib.dlllinux上对应的是.a.so所谓静态、动态是指链接。静态库之所以成为【静态 查看详情

linux下的静态库和动态库

静态库可以把它想象成是一些代码的集合,在可执行程序运行前就已经加到了代码中,成为了执行程序的一部分,一般是以.a为后缀的文件名,Windows下后缀为.lib。静态库的命名也分为三部分,1、前缀:lib,2、库的名称:随意,... 查看详情

linux下静态库动态库的创建与调用(代码片段)

...或者给自己其他的工程项目使用。库的类型分为动态库、静态库。在Linux下动态库的后缀为.so,静态库的后缀为.lib。动态库称为共享库.程序在编译的时需要、运行的时候也需。静态库在编译的时候抽取需要使用的函数进行编... 查看详情

静态库介绍与简单演练及同名资源冲突解决

1、静态库和动态库都是闭源库,不公开源代码。静态库:.a和.framework动态库:.dylib和.framework(iOS9取消了.dylib,使用.tbd替代) 2、静态库和动态库在使用上的区别:静态库:链接时,静态库中使用的文件会被完整的复制到可执... 查看详情

静态和动态链接库

】静态和动态链接库【英文标题】:StaticandDynamicLinkingLibraries【发布时间】:2013-08-2311:53:43【问题描述】:我有一些关于链接库的问题。链接器如何决定我要链接的库是静态链接还是动态链接?是由文件扩展名(.a/.so)决定的吗... 查看详情

静态库与动态库的制作

1、相关知识 (1)、不管是制作静态库还是动态库,都得对.o文件进行打包; (2)、在/lib64目录下,静态库文件.a,动态库文件.so2、静态库 (1)、gcc-cadd.c  ------>生成add.o文件,其中通过参数(-c); (2)、静态库由... 查看详情

linux动态链接库.so文件的创建与使用

...#xff0c;而且更方便升级。 程序函数库可分为3种类型:静态函数库(staticlibra 查看详情

静态与动态库文件

在windows中静态库是以 .lib 为后缀的文件,共享库是以 .dll 为后缀的文件。在linux中静态库是以 .a 为后缀的文件,共享库是以 .so为后缀的文件。以linux下的静态库和动态库为例我们研究一下,首先我们看... 查看详情

linux下的静态库创建与查看,及如何查看某个可执行依赖于哪些动态库

创建静态库:ar-rcstest.a*.o查看静态库:ar-tvtest.a解压静态库:ar-xtest.a查看程序依赖的动态库:readelf-axxx|greplibrary如:可以看到,下面的交叉程序hello执行依赖于如下两个动态库。rebi@ubuntu:~/test$arm-none-linux-gnueabi-readelf-ahello|grep"... 查看详情

linux静态库和共享(动态)库的创建与使用详解(代码片段)

文章目录Linux静态库和共享(动态)库库的介绍使用库有什么好处库制作完成后,如何给用户使用静态库(staticlibrary)静态库的制作ar工具创建lib过程静态库的使用源代码静态库的优缺点优点:缺点:共享库... 查看详情

c中的动态库与静态库

一、介绍1、静态库静态链接库实现链接操作的方式很简单,即程序文件中哪里用到了库文件中的功能模块,GCC编译器就会将该模板代码直接复制到程序文件的适当位置,最终生成可执行文件。使用静态链接库生成的... 查看详情

动态和静态链接库(代码片段)

...在编译时指定所需的头文件和库文件的路径。函数库分为静态链接库(.a、.lib)和动态 查看详情

qt中如何使用动态库.so文件或者静态库.a文件

...StringgetName()constreturnname;private:intid;QStringname;我把它编译成静态文件,Student.pro文件的内容如下:TEMPLATE=libTARGET=DEPENDPATH+=.INCLUDEPATH+=.CONFIG+=staticlib#InputHEADERS+=student.h这样运行之后,就会产生一个libstudent.a文件,如果在其他项目使用... 查看详情