gcc生成静态库和动态库以及其文件的生成和使用

目录

一、用gcc生成静态库和动态库

(一).用gcc生成.a静态库

(二)由.o文件创建动态库

二、使用库的实例1

(一)静态库.a 文件的生成与使用。

 (二)共享库.so 文件的生成与使用

 三、实例2

(一)静态库.a 文件的生成与使用。

 (二)共享库.so 文件的生成与使用

(三)静态库和动态库生成文件比较


一、用gcc生成静态库和动态库

*静态库:在程序编译时会被链接到代码中,程序运行时将不再需要静态库。其后缀是lib。

*动态库:在程序编译并不会链接到代码中,而是在程序运行时被载入,动态库又被称为动态链接库,英文简称DLL,DLL是包含可以由多个程序使用的代码和数据的库,DLL是不可执行文件。

(一).用gcc生成.a静态库

(1)编辑生成hello.h、hello.c和main.c。

用vim文本编辑器分别写出hello.h、hello.c和main.c。

hello.h:

 hello.c:

main.c:

 (2)将hello.c编译成.o文件

1.将程序hello.c通过gcc编译成.o文件,得到hello.o文件。

2.运行ls命令,看是否生成了hello.o文件。

 出现了hello.o文件,即编译成功。

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

静态库文件名的命名以lib为前缀,然后跟库名,扩展名为.a。创建静态库用命令:ar。

此时可将我们的静态库名设置为hello,则静态库文件名为libhello.a。

创建静态库并查看创建是否成功:

输入命令:ar -crv libhello.a hello.o

再输入命令:ls

结果如图:

 出现了libhello.a,创建成功。

(4)在程序里使用静态库

1:输入命令:gcc -o hello main.c -L. -lhello

用命令:./hello运行得到结果

 2.输入命令:gcc main.c libhello.a -o hello

 3.输入命令: gcc -c main.c(生成main.o)

再输入命令:gcc -o hello main.c libhello.a(生成可执行的文件)

(二)由.o文件创建动态库

动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀 lib,但其 文件扩展名为.so。

1.得到动态库文件libhello.so,输入命令:gcc -shared -fPIC -o libhello.so hello。

2.检查是否成功创建,输入命令:ls。

 如图所示,成功创建动态库文件libhello.so。

3.在程序里使用动态库

输入命令:gcc -o hello main.c -L. -lhello

在输入命令:./hello

得到结果如图所示:

二、使用库的实例1

创建A1.c:

创建A2.c:

 创建A.h

创建test.c :

(一)静态库.a 文件的生成与使用。

 1.生成目标文件(A1.o和A2.o)

输入命令:gcc -c  A1.c  A2.c

 2.生成静态库.a 文件

输入命令:ar crv libafile.a A1.o A2.o

 3.使用.a 库文件,创建可执行程序

输入命令:gcc -o test test.c libafile.a和./test

 (二)共享库.so 文件的生成与使用

1.生成目标文件(A1.o和A2.o)

输入命令:gcc -c -fpic A1.c A2.c

2. 生成共享库.so 文件

输入命令:gcc -shared *.o -o libsofile.so

3.使用.so 库文件,创建可执行程序

 输入命令:gcc -o test test.c libsofile.so

发现错误,确实是找不到对应的.so 文件。

这是由于 linux 自身系统设定的相应的设置的原因,即其只在/lib and /usr/lib 下搜索对应 的.so 文件,故需将对应 so 文件拷贝到对应路径。

输入命令:sudo cp libsofile.so /usr/lib和./test来验证

 结果可以成功运行。

还可以直接输入命令:gcc -o -test -test.c -L. -lsofile

 三、实例2

创建sub1.c:

创建sub2.c:

创建sub.h:

 创建main.c:

(一)静态库.a 文件的生成与使用。

 1.生成目标文件(sub1.o和sub2.o)

输入命令:gcc -c  sub1.c  sub2.c

 2.生成静态库.a 文件

输入命令:ar crv libtest.a sub1.o sub2.o

 3.使用.a 库文件,创建可执行程序

输入命令:gcc -o main main.c libtest.a和./main

 (二)共享库.so 文件的生成与使用

1.生成目标文件(sub1.o和sub2.o)

输入命令:gcc -c -fpic sub1.c sub2.c

2. 生成共享库.so 文件并使用.so库文件,创建可执行程序

输入命令:gcc -shared -fPIC -o  libtest.so sub1.o sub2.o和gcc -o main main.c libtest.so 

移动动态库的目的地:sudo cp libtest.so  /usr/lib

得出结果如图:

(三)静态库和动态库生成文件比较

 通过该图可知道,静态库生成的文件比动态库生成的文件更小。

四、Linux GCC 常用命令

(一)简介

GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL 语言,以及支持函数式编程和逻辑编程的 Mercury 语言,等等。

(二)编译

程序如下:

一步到位编译指令:gcc test.c -o test

但实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译 (Compilation)、汇编 (Assembly)和连接(Linking)。

1.预处理:gcc -E test.c -o test.i 或 gcc -E test.c

test.i的部分代码:

2.编译为汇编代码:gcc -S test.i -o test.s

test.s部分代码:

3.汇编:gcc -c test.s -o test.o或直接调用as,即$ as -c hello.s -o hello.o 

4.连接:gcc test.o -o test

(三)多个程序文件的编译

gcc test1.c test2.c -o test 

可细分成下面三步:

gcc -c test1.c -o test1.o

gcc -c test2.c -o test2.o

gcc test1.o test2.o -o test 

(四)检错

gcc -pedantic illcode.c -o illcode -pedantic

-pedantic 编译选项并不能保证被编译程序与 ANSI/ISO C 标准的完全兼容,它仅仅只能用来帮助 Linux 程序员离这个目标越来越近。

除了-pedantic 之外,GCC 还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W 开头,其中最有价值的当数-Wall 了。

所以,在编译程序时带上-Werror 选项,那 么 GCC 会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改,如下:

gcc -Werror test.c -o test

正确时:

 出错时:


1.编译成可执行文件

2.链接

3.强制链接时使用静态链接库

默认情况下, GCC 在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链 接库,如果需要的话可以在编译时加上-static 选项,强制使用静态链接库.

gcc test.c -o test

size test //使用 size 查看大小

ldd test //可以看出该可执行文件链接了很多其他动态库

使用命令“gcc -static test.c -o test”则 会 使 用 静 态 库 进 行 链 接 ,如下图所示:

同样用size test和ldd test进行查看:

可以看出,现在text的代码尺寸变得极大并且说明没有链接动态库。

链接器链接后生成的最终文件为 ELF 格式可执行文件,一个 ELF 可执行文件通常 被链接为不同的段,常见的段譬如.text、.data、.rodata、.bss 等。

(六)分析 ELF 文件

1.ELF 文件的段

   ELF 文件格式如下图所示,位于 ELF Header 和 Section Header Table 之间的都 是段(Section)。一个典型的 ELF 文件包含下面几个段:

.text:已编译程序的指令代码段。

.rodata:ro 代表 read only,即只读数据(譬如常数 const)。

.data:已初始化的 C 程序全局变量和静态局部变量。

.bss:未初始化的 C 程序全局变量和静态局部变量。

.debug:调试符号表,调试器用此段的信息帮助调试。

输入命令:readelf -S test

结果如图:

2.反汇编 ELF

由于 ELF 文件无法被当做普通文本文件打开,如果希望直接查看一个 ELF 文件包 含的指令和数据,需要使用反汇编的方法。

输入命令:objdump -D test进行反汇编

再使用 objdump -S 将其反汇编并且将其 C 语言源代码混合显示出来:

输入命令:gcc -o test -g test.c

objdump -S test

四、总结

通过此次作业,我学会了gcc编译的静态和动态库的建立以及文件的编译运行,对我的启发很大,同时对于ubuntu系统也有了更深刻的理解和使用。

参考博客:https://blog.csdn.net/qq_43279579/article/details/109026927

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值