gcc分别链接静态库和动态库生成可执行文件
gcc分别链接静态库和动态库生成可执行文件
本文分别通过链接静态库和动态库来编译可执行文件,在使用gcc编译的过程中了解链接静态库和动态库的区别与联系,同时深入理解Linux系统上是如何将源程序一步步的编译组装成可执行文件的。
目录
(一)库文件
1.什么是库
2.库命名规则
3.查找依赖库
(二)编译时链接静态库文件
1.源程序
2.编译静态库文件libx2.a
3.链接为可执行文件main
(三)编译时链接动态库文件
1.编译动态库文件libx2.so
2.链接为可执行文件
3。链接静态库与动态库生成可执行文件的区别
(四)总结
(一)库文件
1.什么是库
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种。
静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要该静态库。
动态库在程序编译时并不会被链接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。
2.库命名规则
静态库
静态库的名字一般为libxxx.a,其中xxx是该lib的名称。
动态库
动态库的名字一般为libxxx.so.major.minor,xxx是该lib的名称,major是主版本号, minor是副版本号。
3.查找依赖库
使用命令ldd可以查看一个可执行文件依赖的动态库。
$ ldd main
linux-vdso.so.1 (0x00007ffc42bcc000)
libx2.so => /usr/lib/libx2.so (0x00007ff37f0fc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff37ed0b000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff37f500000)
由此可见,main可执行文件依赖于linux-vdso、libx2、libc、ld-linux-x86-64这四个动态库。
(二)编译时链接静态库文件
1.源程序
main.c(主函数)
#include"sub1.h"
#include"sub2.h"
#include
int main()
{
int x=2,y=9,n;//定义x和y变量
printf("%d/%d=%.2f\n",y,x,x2x(x,y));//输出处理后的值,保留两位小数
printf("请输入斐波那契的第n项值:");
scanf("%d",&n);
printf("斐波那契数列第%d项为%d\n",n,x2y(n));//输出斐波那契数列的第n项
return 0;
}
sub1.h
#ifndef __SUB1_H
#define __SUB1_H
float x2x(int a,int b);//计算b除以a
#endif
sub1.c(子函数1)
#include "sub1.h"
/*******************/
/*参数:a */
/*参数:b */
/* 返回值:b/a */
/*******************/
float x2x(int a,int b)
{
float ans;
ans=(float)b/a;
return ans;
}
sub2.h
#ifndef __SUB2_H
#define __SUB2_H
int x2y(int);//计算斐波那契数列的第n项值
#endif
sub2.c(子函数2)
#include "sub2.h"
/*********************************/
/*参数:n */
/* 返回值:第n项斐波那契数列值 */
/*********************************/
int x2y(int n)
{
int a=1,b=1,i;
long c=0;
if(n<3) return 1;
else
{
for(i=0;i<=n-3;i++)
{
c=a+b;
a=b;
b=c;
}
return c;
}
}
2.编译静态库文件libx2.a
编译.o目标文件
输入命令gcc -c main.c sub1.c sub2.c可以编译得到main.o、sub1.o、sub2.o三个目标文件
编译libx2.a静态库文件
使用命令ar -crv libx2.a sub1.o sub2.o编译生成libx2.a静态库文件。
3.链接为可执行文件main
使用命令gcc main.o libx2.a -o main链接main.o和libx2.a文件生成可执行文件main
执行可执行文件main
使用命令./main执行该可执行文件
测试是否真的静态库链接成功
删除静态库libx2.a目标文件,再次执行该可执行文件
以上说明静态库链接生成的可执行文件运行时不需要该静态库,因为该静态库已经被编译到可执行文件中了。
(三)编译时链接动态库文件
1.编译动态库文件libx2.so
.o目标文件已经在上面编译静态库文件时生成了,因此这里直接编译动态库文件。
使用命令gcc -shared -fPIC -o libx2.so sub1.o sub2.o编译生成动态库文件libx2.so
2.链接为可执行文件
使用命令gcc main.o libx2.so -o main链接两个目标文件生成可执行文件main
执行生成的可执行文件main
使用命令./main执行该可执行文件main
发现报错如下:
原因:
程序在运行时, 会在/usr/lib 和/lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。
解决方法:
将libx2.so 复制到目录/usr/lib 中,再次执行./main运行(若提示权限不够则以使用sudo mv libx2.so /usr/lib该命令)
使用命令ldd main查看main可执行文件的依赖项
3。链接静态库与动态库生成可执行文件的区别
静态库生成的可执行文件为8520字节,动态库生成的可执行文件为8456字节。从而可见动态库生成的可执行文件要比静态库生成的要更小,但是链接动态库需要依赖于该动态库。
(四)总结
通过使用静态库和动态库分别链接生成可执行文件main,我深入的了解到了不同库函数的链接的作用是不一样的。静态库链接是直接在程序编译时就将其组装到一起,可以不依赖于静态库就能运行;而动态库链接是在程序运行时才将其载入内存运行且不能够缺少,否则不能运行。
感谢该博主我的启发:
关于Linux静态库和动态库的分析
gcc分别链接静态库和动态库生成可执行文件相关教程
【嵌入式作业3】Linux中gcc及库的知识及操作
【嵌入式作业3】Linux中gcc及库的知识及操作 Ubuntu下gcc库操作 一、在 Linux 中创建静态库和动态库 1、编辑生成程序 hello.h、hello.c 和 main.c 2、将 hello.c 编译成.o 文件 3、由.o 文件创建静态库。 4、在程序中使用静态库 5、由.o 文件创建动态库文件。
如何检测域名链接是否在微信中被屏蔽
如何检测域名链接是否在微信中被屏蔽 出现以下几点,证明你的域名被微信拦截了 ?链接报红:提示已停止访问该网页{域名已被微信拦截} ?域名能正常访问{未被微信拦截} ?非微信官方页面,继续访问将转成手机其它浏览模式 ?有用户投诉及腾讯安全中心检测该网页内容涉
opencv-python应用轮廓相关知识,对图片进行处理,分别用矩形、
opencv-python应用轮廓相关知识,对图片进行处理,分别用矩形、圆形识别饮料,输出各自的中心点,矩形的长宽、圆形的半径,得到四个极点。 要求:应用轮廓相关知识,对图片进行处理,分别用矩形、圆形识别饮料,输出各自的中心点,矩形的长宽、圆形的半径,得
gcc编译器背后的故事
gcc编译器背后的故事 1.创建一个a文件夹,然后在a文件夹中创建三个子程序a.h、a.c以及main.c 代码如下: mkdir acd avim a.hvim a.cvim main.c 实例显示: 子程序a.h内容: #ifndef A_H#define A_Hvoid a(const char *name)#endif 子程序a.c内容: #includest
编译器的相关
编译器的相关 目录 一、gcc生成.a和.so文件 (一)仿照实验 (二)比较.a和.so文件 二、GCC不是一个人在战斗 三、了解实际程序是如何借助第三方库函数完成代码设计 (一)Linux curses库 (二)体验Windows的BBS 四、总结 五、参考资料 可执行程序是如何被组
Udesk即时通讯网页插件专用链接传参介绍
Udesk即时通讯网页插件专用链接传参介绍 作者:张振琦 在《Udesk即时通讯(IM)网页插件入门》中说到了即时通讯的专用链接,也演示了浏览器直接访问和网页iframe加载的效果。本篇来介绍一下,专用链接支持的参数,通过给专用链接添加参数,使其使用场景更加丰
Linux系统下GCC编译器的使用以及其背后的“帮手”
Linux系统下GCC编译器的使用以及其背后的“帮手” 本文目录 一.GCC中的动态库和静态库的使用 1.可执行程序是如何被组装的? 2.用gcc生成静态库和动态库 3.静态库.a与.so库文件的生成与使用 4.一个生成静态库和动态库简单程序小练习 二.Linux中GCC常用命令 1.L
GCC编译器的使用及背后的故事
GCC编译器的使用及背后的故事 目录 一、GCC编译器的使用 1、创建一个 hello.c 2、程序的编译过程 3、多个程序文件的编译 二、GCC编译器背后的故事 1.准备 2.编译过程 三、分析 ELF 文件 1.ELF 文件的段 2.反汇编 ELF 四、汇编代码“hello.asm”编译生成可执行