Linux里的gcc

首言

本文主要通过举例来说明在 Linux 中如何创建静态库和动态库,以及使用它们

一、用gcc生成.a静态库和.so动态库

1.静态库和动态库

(1)静态库

静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库

(2)动态库

动态库在程 序编译时并不会被连接到目标代码中,而是在程序运行是才被载入

2.静态库与动态库的区别

(1)链接方式:静态库在编译时链接,动态库在运行时链接。
(2)文件大小:静态库较大,包含了所有的函数代码;动态库较小,在运行时再加载需要的代码。
(3)依赖性:静态库不依赖运行库,可以独立运行;动态库依赖运行库。
(4)安全性:静态库相对安全,不容易被篡改;动态库可能被篡改。
(5)部署:发布应用时需要带上静态库;只需发布动态库,应用本身不需要带库。
总的来说,静态库更独立,安全性好一些;动态库体积小,更灵活,但依赖性强,安全性差。一般来说,系统底层的通用库采用静态库,而应用程序的非关键库采用动态库。

二、创建静态库和动态库

1.创建前的准备

在创建静态库和动态库之前,需要准备三个源程序,分别是公用函数的.h和.c文件,以及一个主程序的.c文件,本文的例子是一个hello的公用函数。

(1)创立作业目录

此做法主要是为了能够保存此次用到的各种文件,代码如下:

#mkdir test1
#cd test1

(2)创建hello.h

#ifndef hello_h
#define hello_h

void hello(const char *name);
#endif

hello.h是我们建立的函数的头文件,里面应该包括函数的声明

(3)创建hello.c

#include<stdio.h>
void hello (const char *name)
{
        printf("hello %s!\n",name);
}

该源程序需要包括我们函数具体所执行的内容,同时需要引入头文件

(4)创建main.c

#include"hello.h"
int main()
{
        hello("everyone");
        return 0;
}

主程序里面应该包含我们要用的函数的头文件,也就是我们创立的hello.h

2.将hello.c文件生成.o目标文件文件

无论静态库,还是动态库,都是由.o 文件,这也是为什么选哟生成这里会用到gcc命令

基本语法 gcc [option] [filename],下表为不同选择的语法作用

-c

 将输入的.c源文件生成.o的目标源文件

-o可以指定编译后输出的可执行文件的名称
-E编译并产生汇编文件
-S对.c源文件进行预处理

3.由.o 文件创建静态库 

静态库创建规范:lib+静态库名+.a

运用的命令:-ar

语法:ar[-dmpqrtx][cfosSuvV][a<成员文件>][b<成员文件>][i<成员文件>][备存文件][成员文件]

含义:例如我们可以用ar -rv libtest.a hello.o hello1.o来生成一个库,库名字是test,链接时可以用-ltest链接。该库中存放了两个模块hello.o和hello1.o。 

ar命令的参数如下:

参数意义
-r将objfile文件插入静态库尾或者替换静态库中同名文件
-x从静态库文件中抽取文件objfile
-t打印静态库的成员文件列表
-d从静态库中删除文件objfile
-s重置静态库文件索引
-v显示详细信息
-c创建静态库文件

 本文创建的是名字为myhello的静态库,同时用ls命令查看创建结果,如下:

4.在程序中使用静态库

 (1)生成目标程序hello

这里的目标程序也就是可执行文件,在本文也就是将main.c和libmhyhello.a编译后的可执行文件的名称取名为hello

这里有三种方法,如下:

法一:

法二:

法三:先生成main.o目标文件,再生成可执行文件

(2)验证

删除静态库文件试试公用函数 hello 是否真的连接到目标文件 

5.由.o文件创建动态库文件

动态库创建规范:lib+动态库名+.so

 

6.在程序中使用动态库

这里使用到的命令与静态库一样,本文直接采用静态库中的第一个命令,结果如下:

 由结果可以看出,出错了,原因是找不到这个动态库文件,这是因为程序在运行时, 会在/usr/lib 和/lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。因此,我们需要将建立的动态库libmyhello.so复制到目录/usr/lib中,如下:

注意:因为这里涉及到地址更换,所以应该先获取权限,再将libmyhello.so复制到目录/usr/lib中。

由上图我们可以看出当成功将文件复制到/usr/lib后程序就可以正常运行了。

三、对比

由以上过程我们可以得出,那么接下来我们将继续探索当静态库和动态库同名时,gcc命令会优先使用哪个库文件。

1.准备工作

我们需要先删除除最开始准备的.c和.h以外的所有文件。

2.创建静态库和动态库

3.运行gcc

由上图可视,出现错误,并且这个错误与动态库出现的一致,因此可以得出结论:当静态库和动态库同名时,gcc会优先使用动态库。 

四、实际演示

创建两个函数x2x、x2y,和一个主函数

1.静态库

将3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。

最终结果如下:

2.动态库 

将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序,记录文件的大小

五、总结

1.静态库

  • 静态库是将目标文件(.o文件)打包成一个单独的库文件(.a文件)的方式。
  • 在静态库中,目标文件的代码被完全复制到调用程序中,与调用程序链接在一起。
  • 静态库在编译时会被链接到可执行文件中,因此在运行时不需要额外的库文件。
  • 优点是简单易用,不需要依赖额外的库文件。
  • 缺点是每个调用程序拥有一份自己的代码副本,会占用更多的磁盘空间和内存。

2.动态库

  • 动态库是将目标文件编译成具有共享特性的库文件(.so文件)
  • 在动态库中,目标文件的代码在运行时被动态加载到内存中,并与调用程序共享。
  • 动态库可以在多个程序之间共享,减少了代码的冗余,节省了空间。
  • 在运行时,调用程序需要动态链接器在系统中找到并加载动态库。
  • 优点是节省了磁盘空间,可以在多个程序之间共享。
  • 缺点是在运行时需要依赖相应的动态库文件。

       生成静态库将目标文件的代码完全复制到调用程序中,不需要依赖额外的库文件,但会占用更多的磁盘空间和内存。生成动态库允许多个程序共享库文件,减少了冗余代码,但需要在运行时依赖相应的动态库文件。选择静态库还是动态库取决于具体需求和应用场景。

六、参考

(1)https://blog.csdn.net/chen1415886044/article/details/104395351 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值