linux gcc编译生成库,gcc分别链接静态库和动态库生成可执行文件

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三个目标文件

c8bace89485d65314aee8cdb527dfb2d.png

编译libx2.a静态库文件

使用命令ar -crv libx2.a sub1.o sub2.o编译生成libx2.a静态库文件。

8532d4e43b6948ae63555082e3f70c86.png

3.链接为可执行文件main

使用命令gcc main.o libx2.a -o main链接main.o和libx2.a文件生成可执行文件main

1df9c83953e08da04d3e9016459d919c.png

执行可执行文件main

使用命令./main执行该可执行文件

5fe25c6c59cb51839b6df3c6ff5469ba.gif

测试是否真的静态库链接成功

删除静态库libx2.a目标文件,再次执行该可执行文件

2f0c17de1029e42a77dd5c8577eb6d35.png

以上说明静态库链接生成的可执行文件运行时不需要该静态库,因为该静态库已经被编译到可执行文件中了。

(三)编译时链接动态库文件

1.编译动态库文件libx2.so

.o目标文件已经在上面编译静态库文件时生成了,因此这里直接编译动态库文件。

使用命令gcc -shared -fPIC -o libx2.so sub1.o sub2.o编译生成动态库文件libx2.so

69a1bea9b95469603d9abc03c5bb6057.png

2.链接为可执行文件

使用命令gcc main.o libx2.so -o main链接两个目标文件生成可执行文件main

0951381986cbe2ace464006fe1be9d1f.png

执行生成的可执行文件main

使用命令./main执行该可执行文件main

发现报错如下:

f2329928bb7e63516ec12c1b544a925d.png

原因:

程序在运行时, 会在/usr/lib 和/lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。

解决方法:

将libx2.so 复制到目录/usr/lib 中,再次执行./main运行(若提示权限不够则以使用sudo mv libx2.so /usr/lib该命令)

使用命令ldd main查看main可执行文件的依赖项

d6ffaf479c80a245a474c1635efd60c3.png

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”编译生成可执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值