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
    评论
动态库静态库是在程序编译期间链接的库文件,用于提供可重用的代码和函数,从而节省编写代码的时间和减少代码重复。下面是它们的使用生成方法: 1. 静态库 静态库是一种编译时链接的库文件,它会将库文件的代码和函数复制到可执行程序中。在使用静态库时,需要将静态库文件路径和名称添加到编译器的链接器参数中,例如: ``` $ gcc main.c -L./lib -lfoo -o main ``` 其中,`-L./lib` 表示将库文件所在的目录添加到链接库的搜索路径中,`-lfoo` 表示链接名为 `libfoo.a` 的库文件,`-o main` 表示将编译生成的可执行文件命名为 `main`。 生成静态库的方法如下: ``` $ gcc -c foo.c -o foo.o $ ar rcs libfoo.a foo.o ``` 其中,`-c foo.c -o foo.o` 表示将 `foo.c` 编译成目标文件 `foo.o`,`ar rcs libfoo.a foo.o` 表示将目标文件 `foo.o` 打包成静态库 `libfoo.a`。 2. 动态库 动态库是一种在运行时链接的库文件,它不会将代码和函数复制到可执行程序中,而是在程序运行时动态加载。在使用动态库时,需要将动态库的路径和名称添加到程序运行环境的搜索路径中,例如: ``` $ export LD_LIBRARY_PATH=./lib $ gcc main.c -lfoo -o main ``` 其中,`export LD_LIBRARY_PATH=./lib` 表示将库文件所在的目录添加到动态库的搜索路径中,`-lfoo` 表示链接名为 `libfoo.so` 的动态库,`-o main` 表示将编译生成的可执行文件命名为 `main`。 生成动态库的方法如下: ``` $ gcc -fPIC -c foo.c -o foo.o $ gcc -shared -o libfoo.so foo.o ``` 其中,`-fPIC` 表示生成位置无关的代码,`-c foo.c -o foo.o` 表示将 `foo.c` 编译成目标文件 `foo.o`,`-shared -o libfoo.so foo.o` 表示将目标文件 `foo.o` 打包成动态库 `libfoo.so`。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值