网站建设 事迹,昆明做整站优化,竞拍网站模板,婚纱摄影网站的设计思路库是指在我们的应用中#xff0c;有一些公共代码是需要反复使用#xff0c;就把这些代码编译为库文件;在链接步骤中#xff0c;链接器将从库文件取得所需的代码#xff0c;复制到生成的可执行文件中。
Linux中常见的库文件有两种#xff0c;一种.a为后缀有一些公共代码是需要反复使用就把这些代码编译为库文件;在链接步骤中链接器将从库文件取得所需的代码复制到生成的可执行文件中。
Linux中常见的库文件有两种一种.a为后缀为静态库另一种以.so为后缀为动态库。 一、静态库 可重定位目标文件以一种特定的方式打包成一个单独的文件并且在链接生成可执行文件时从这个单独的文件中“拷贝它自己需要的内容到最终的可执行文件中。这个单独的文件称为静态库。Linux中这类库的名字一般是libxxx.a。
1.创建步骤
将add.c sub.c创建成静态库文件:
创建add.c sub.c
#add.cint add (int a, int b)
{return a b;
}#sub.cint sub (int a, int b)
{return a - b;
}
对add.c sub.c编译成可重定位目标文件
gcc -c add.c -o add.o
gcc -c sub.c -o sub.o
利用ar工具创建静态库: ar rcs lib 库名.a所有可重定位目标文件
#生成静态库
ar rcs libmath.a add.o sub.o
2.静态库的使用
制作使用libmath.a静态库的程序
创建main.c
#includestdio.hint add(int a,int b);
int sub(int a,int b);int main(int argc, char* argv[])
{int a5,int b3;printf(ab%d\n,add(a,b));printf(a-b%d\n,sub(a,b)); return 0;
}
编译main.c
编译时要将静态库libmath.a加上gcc选项:
l:指定库名(库的文件名为libxxx.a库名为xxx)L:指定库路径static:使用静态链接
gcc -static main.c -l math -L ./
#注意要先运行main.c后运行静态库文件./a.out 特别注意必须把-l math 放在后面。放在最后时它是这样的一个解析过程:
链接器从左往右扫描可重定位目标文件和静态库扫描main.c时发现两个未解析的符号add和sub记住这两个未解析的符号扫描libmath.a找到了前面未解析的符号因此提取相关代码最终没有任何未解析的符号编译链接完成
那如果将-l math放在前面又是怎样的情况呢?
链接器从左往右扫描可重定位目标文件和静态库扫描libmath.a由于前面没有任何未解析的符号因此不会提取任何代码扫描main.c发现未解析的符号add和sub扫描结束还有两个个未解析的符号因此编译链接报错
生成可执行文件大小 生成的可执行文件大小为826k 由于最终生成的可执行文件中已经包含了add和sub相关的二进制代码因此这个可执行文件在一个没有libmath.a的Linux系统中也能正常运行。
二、动态库 动态库和静态库类似但是它并不在链接时将需要的二进制代码都“拷贝到可执行文件中而是仅仅“拷贝”一些重定位和符号表信息这些信息可以在程序运行时完成真正的链接过程。Linux中这类库的名字一般是libxxx.so。(shared object)
1.创建步骤
//先编译成可重定位目标文件(生成与位置无关的代码-fPIC)
gcc -c add.c -o add.o -fPIC
gcc -c sub.c -o sub.o -fPIC
//使用gcc -shared 制作动态库
gcc -shared -o libmath.so add.o sub.o
-fPC作用生成与位置无关的代码
2.动态库的使用 通常我们编译的程序默认就是使用动态链接
gcc main.c -o main -l math -L ./ 通过动态库链接的程序只有8.5k. 通过 ldd命令来观察可执行文件链接了哪些动态库: 因为没有把 libmath.so 中的二进制代码“拷贝可执行文件中程序在其他没有上面的动态库时将无法正常运行。
3.找不到动态库 运行可以执行程序./main出错!!! ldd main -- not found 链接器:工作于链接阶段工作时需要-l和L 动态链接器:工作于程序运行阶段工作时需要提供动态库所在目录位置。 原因:没有提供动态库的位置
解决方式:
通过环境变量(临时生效): export LD_LIBRARY_PATH动态库路径环境变量写入配置文件~/.bashrc使用绝对路径)生效方法: .~/.bashrc或source ~/.bashrc 或 重启终端拷贝自定义动态库到lib(标准C库所在目录位置)(不推荐) 【注】只是临时生效。关闭终端再重启时使用./main还会报错。如果想要一直生效需要写在配置文件中。
动态库绝对路径写到/etc/ld.so.conf配置文件中生效方法: sudo ldconfig
三、静态库和动态库的区别 静态库被使用目标代码最终和可执行文件在一起(它只会有自己用到的)而动态库与它相反它的目标代码在运行加载时链接。正是由于这个区别会导致下面所介绍的这些区别。
1可执行文件大小 静态链接的可执行文件要比动态链接的可执行文件要大得多因为它将需要用到的代码从二进制文件中“拷贝”了一份而动态库仅仅是复制了一些重定位和符号表信息。
2.扩展性与兼容性 如果静态库中某个函数的实现变了那么可执行文件必须重新编译而对于动态链接生成的可执行文件只需要更新动态库本身即可不需要重新编译可执行文件。正因如此使用动态库的程序方便升级和部署。
3依赖原库文件 静态链接的可执行文件不需要依赖其他的内容即可运行而动态链接的可执行文件必须依赖动态库的存在。所以如果你在安装一些软件的时候提示某个动态库不存在的时候也就不奇怪了。
即便如此系统中一般存在一些大量公用的库所以使用动态库并不会有什么问题。
4.加载速度 由于静态库在链接时就和可执行文件在一块了而动态库在加载或者运行时才链接因此,对于同样的程序静态链接的要比动态链接加载更快。所以选择静态库还是动态库是空间和时间的考量。但是通常来说牺牲这点性能来换取程序在空间上的节省和部署的灵活性时值得的。
5.库的制作复杂度 相对来讲动态库的处理要比静态库要复杂例如如何在运行时确定地址?多个进程如何共享一个动态库?当然这些我们不需要关注。另外动态库版本的管理也是一项技术活。