库文件制作

库文件的作用

库文件分为静态库和动态库,我在学习单片机RTOS想看底层实现代码的时候往底层找的时候就找不到了。这就是为了保护代码的隐私!使用了动态库。库文件是二进制文件因此别人可以通过这个动态库和对应的头文件就可以达到既然使用者知道函数的使用方法,也可以让使用者正确的使用这个函数,这个使用者是看不到这个函数是如何实现的!!!

静态库和动态库的区别

静态库和动态库的区别体现在程序的链接阶段:
静态库在程序的链接阶段被复制到了程序中;
动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。
使用动态库系统只需载入一次,不同的程序可以得到内存中相同的动态库的副本,因此节省了
很多内存,而且使用动态库也便于模块化更新程序。

库文件的命名:
必须使用lib作为前缀: 比如 libDeployPkg.so.0 / libhgfs.so.0 .....
静态库一般以 .a 为后缀 , 动态库一般以.so为后缀
库文件会有不同的版本, 一般写在后缀后面, 比如 lib.a.so.0.1.2

1 libc.so.1.0.3
2 lib 库文件的前缀
3 c 库的名字(链接库文件时 ,只需要写上该名字)
4 .so 后缀(so为动态库/共享库 a 则是静态库)
5 .1 库文件的版本号
6 .0.3 修正号

如何制作库文件

1、不管需要制作的是静态库还是动态库,原材料都是.o文件 (可重定位文件)
2、库文件内部不允许出现主函数main

gcc xxx.c -o xxx.o -c //一般不会直接使用这个制作库文件的命令

1.静态库

1.制作.o文件

将要制成库文件的c文件生成可执行文件.o,需要注意的是命令使用必须在c文件目录下

1 $ gcc swap.c -o swap.o -c -fPIC -I../inc
2 $ gcc max.c -o max.o -c -fPIC -I../inc
3
4
5 -c 是让编译在在生可重定位文件后停止工作
6 -fPIC 则是告诉编译器生成于地址无关的可执行文件
7
8 关于-fPIC 选项《动态链接库》的说法:
9 如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位,
10 重定位会修改代码段的内容,
11 这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.
12 每个copy都不一样,取决于 这个.so文件代码段和数据段内存映射的位置(地址).
13 -I../inc 将.o文件放入上一级目录下的inc文件夹里
14

经过试验在虚拟机中会出错,但是在WSL中不会出现以下错误

 如果出现错误:(.text+0x24): undefined reference to `main'

gcc -shared 文件名.c -o 生成的文件名.o -fPIC -I头文件地址

 2. 把以上生成的两个.o文件一起编译生成静态库文件

ar -rcs libmy_lib.a max.o swap.o
ar //是一种编译工具
-rcs //将库文件连接起来(比如需要将多个.o文件生成一个库文件)
libmy_lib.a //设置生成静态库的名称为libmy_lib.a
max.o swap.o //将这两个文件编译成一个库文件

3.使用静态库文件

1、指定包含静态库里函数头文件的地址

2、指定库文件路径

3、链接库的名称

4、指定生成的二进制文件名(这个二进制文件就是我们最终执行的文件)

1 $ gcc src/*.c -I./inc -L./lib -lmy_lib -o bin/main
2 $ gcc 编译器
3 src/*.c 源文件
4 -I./inc -I 指定头文件路径为 ./inc
5 -L./lib -L 指定库文件路径为 ./lib
6 -lmy_lib -l 链接库名 为 my_lib
7 -o bin/main -o 指定生成二进制文件为 bin/main

2.动态库

1.先获取.o文件

1 $ gcc swap.c -o swap.o -c -fPIC -I../inc
2 $ gcc max.c -o max.o -c -fPIC -I../inc

2.把.o 文件制作成动态链接库

1 gcc -shared -fPIC -o libmy_lib.so *.o
2 gcc 编译器
3 -shared 生成动态链接库
4 -fPIC 生成于地址无关的二进制文件
5 -o libmy_lib.so 输出一个动态链接库名字 libmy_lib.so
6 *.o 所有的.o文件

3. 如何使用动态链接

1、如何编译

编译生成二进制文件我们仍然要指定编译文件(.c,库文件,头文件)的地址,库的名称

$ gcc src/*.c -I./inc -L./lib -lmy_lib -o bin/mian

2、运行生成的二进制文件(mian)

1 $ ./mian
2 ./mian: error while loading shared libraries: libmy_lib.so:
3 cannot open shared object file:
4 No such file or directory

运行后出错,找不到目标文件,因为动态库在我们运行程序的时候需要加载到内存中,加载的动作由系统来完成。系统并不知道我们的库在哪里,因此加载失败。

解决:

方法1 [ 推荐使用 ]:
系统虽然不知道我们自己的库在哪里, 但是它有一些默认路径(在环境变量中预先写好的路径) 。因此我们可以把自己的动态库文件方到系统默认的路径下即可 (/usr/lib 或者 /lib )

 $ sudo cp lib/libmy_lib.so /usr/lib/ // 把自己的库文件拷贝到 /usr/lib

方法2 :把库所在的路径写入(添加)到环境变量中

先确定自己的库路径在哪里 (不推荐使用共享路径)
1打开配置文件( .bashrc)

$ vim ~/.bashrc

2在文件末尾添加一行

1 export LD_LIBRARY_PATH=/home/even/my_lib:$LD_LIBRARY_PATH
2
3 export 临时修改环境变量
4 LD_LIBRARY_PATH= 修改的是库的路径
5 /home/even/my_lib 需要添加的具体你自己的库的路径
6 : 分隔符
7 $LD_LIBRARY_PATH 从新引用原有的路径 类似 a += b 

3可以重新打开新的终端或者重新生效配置脚本

$ source ~/.bashrc //重新生效 ~/.bashrc文件

4运行二进制文件

./mian

方法3 :在系统的默认路径下添加一个新的路径
先确定自己的库路径在哪里 (不推荐使用共享路径)

打开配置文件 (libc.conf)

$ sudo vim /etc/ld.so.conf.d/libc.conf

在文件末尾添加新的一行
写入你自己的库的路径
从新生效库的配置文件

$ sudo ldconfig

运行二进制文件

./mian

注意事项

如果动态库于静态库名字一样,而且放一起,则编译器默认使用动态链接
如何指定让编译器使用静态库 -static

1 $ gcc src/*.c -o bin/main -L./lib -I./inc -lmy_lib -static
2 // -static 则是让编译器选择静态编译 程序会变得很大
3 // 以后运行的时候完全不需要任何的动态库支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值