31-库文件的制作与使用——静态库文件与动态库文件

31-库文件的制作与使用——静态库文件与动态库文件

一、库文件介绍

库文件是在计算机编程中用来存放变量函数的文件,提供给开发者开箱即用的资源。库文件分为静态库动态库两种,二者在程序链接阶段的行为不同:

  • 静态库:在程序的链接阶段被复制到程序中。每次程序运行时,静态库内容都被完整复制,因此占用更多的内存,但无需依赖外部文件,适合独立分发。
  • 动态库:在程序的链接阶段不被复制,而是程序运行时由系统动态加载到内存中。多个程序可以共享一个动态库实例,节省内存并便于模块化更新

1.1 静态库和动态库的区别

  • 静态库

    • 在编译时将库的内容复制到程序中。
    • 优点:无需担心运行时缺失库文件。
    • 缺点:占用更多内存,不便于更新。
    • 类似于书店,只卖不借。
  • 动态库

    • 运行时加载,不在编译时复制到程序中。
    • 优点:节省内存,提高程序执行效率。
    • 缺点:需要运行时动态库的支持。
    • 类似于图书馆,只借不卖。

1.2 库文件的命名规则

  • 前缀 lib:例如 libDeployPkg.so.0
  • 静态库后缀 .a
  • 动态库后缀 .so
  • 版本号在后缀之后:例如 libc.so.1.0.3

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

二、制作库文件

制作静态库和动态库的原材料都是 .o 文件(可重定位文件),这些文件不能包含主函数 main

2.1 静态库的制作

  1. 生成 .o 文件

    gcc -c -fPIC -I../inc swap.c -o swap.o
    gcc -c -fPIC -I../inc max.c -o max.o
    
    • -c:生成可重定位文件后停止。
    • -fPIC:生成与地址无关的可执行文件。

fPIC 选项《动态链接库》的说法:如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位, 重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每个copy都不一样,取决于 这个.so文件代码段和数据段内存映射的位置(地址)

  1. 生成静态库文件

    ar -rcs libmy_lib.a swap.o max.o
    

rcs是生成静态库文件
三个参数,分别表示:

  • r:替换已存在的文件。
  • c:创建新的库文件。
  • s:生成索引,加快库文件的查找速度。
  1. 使用静态库文件

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

-I是指定头文件的路径,-L是指定库文件的路径,-l是指定库文件的名字,-o是生成可执行文件的名字(路径)。

在这里插入图片描述

在这里插入图片描述

2.2 动态库的制作

  1. 生成 .o 文件

    gcc -c -fPIC -I../inc swap.c -o swap.o
    gcc -c -fPIC -I../inc max.c -o max.o
    
  2. 生成动态库文件

    gcc -shared -fPIC -o libmy_lib.so.0 swap.o max.o
    

-shared 表示生成动态库文件
-fPIC 表示生成与地址无关的可执行文件
-o 表示生成动态库文件的名字(路径)

在这里插入图片描述

  1. 生成动态库文件的软链接

    ln -s libmy_lib.so.0 libmy_lib.so
    

注意:软链接是非必须的,但是在版本管理中,我们通常需要为每个版本的库文件创建一个软链接,以便于管理。
为什么需要生成软链接?

  • 版本管理:动态库的版本会不断更新,例如从 libmy_lib.so.0 更新到 libmy_lib.so.1。通过软链接,你可以将 libmy_lib.so 指向最新的版本,无需修改代码或重新编译。
  • 编译方便:编译器和链接器通常会查找没有版本号的库文件名称(例如 libmy_lib.so),然后自动链接到相应的库文件。如果没有软链接,编译器可能会找不到库文件,导致编译失败。
  • 简化使用:软链接可以让你在编写 Makefile 或其他编译脚本时更加简洁,不需要关注具体的库文件版本号。
  1. 使用动态库文件
    • 编译:

      gcc src/*.c -I./inc -L./lib -lmy_lib -o bin/main
      
    • 运行:

      ./main
      
2.2.1 动态库加载问题及解决方法

直接使用会报错:

./mian: error while loading shared libraries: libmy_lib.so:cannot open shared object file: No such file or directory

原因是:
因为动态库在我们运行程序的时候需要加载到内存中,加载的动作由系统来完成。系统并不知道我们的库在哪里,因此加载失败。

  1. 方法一:将库文件放入系统默认路径(推荐)。–> /usr/lib/或者/lib

    sudo cp lib/libmy_lib.so /usr/lib/
    
  2. 方法二:将库路径添加到环境变量。

    vim ~/.bashrc
    

    在末尾添加:

    export LD_LIBRARY_PATH=/home/even/my_lib:$LD_LIBRARY_PATH
    

LD_LIBRARY_PATH 是一个环境变量,用于指定动态链接库的搜索路径。当程序运行时,系统会按照这个路径来查找动态链接库。:为分隔符,$LD_LIBRARY_PATH表示原来的路径。

重新加载配置文件:

source ~/.bashrc
  1. 方法三:在系统默认路径下添加新的路径。

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

    添加库路径:

    /home/even/my_lib
    

    重新生效配置文件:

    sudo ldconfig
    

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

2.3 静态编译选项

  • 指定使用静态库:

    gcc src/*.c -o bin/main -L./lib -I./inc -lmy_lib -static
    

三、 隐藏命令行路径

前面得路径太长了,可以进行隐藏:

  1. 编辑 .bashrc

    vim ~/.bashrc
    
  2. 添加以下内容:

    export PS1='[\u@\h \W]\$ '
    
  3. 重新加载配置文件:

    source ~/.bashrc
    

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写的什么石山代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值