Linux静态库和动态库的制作与使用

一、什么是库

  • 库文件是计算机上的一类文件,可以简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类。
  • 库是特殊的一种程序,编写库的程序和编写一般的程序区别不大,只是库不能单独运行。
  • 库文件有两种,静态库和动态库(共享库),区别是:静态库在程序的链接阶段被复制到了程序中;动态库在链接阶段没有复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。
  • 库的好处:1. 代码保密    2. 方便部署和开发

二、静态库

1、命名规则
  • libxxx.a
      lib :前缀(固定)
      xxx :库的名字,自己起
      .a :后缀(固定)
2、制作

实验代码
(1)gcc 获得 .o 文件

nowcode@nowcode:~/test01/calc$ gcc -c add.c div.c mult.c sub.c
nowcode@nowcode:~/test01/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

(2)将 .o 文件打包,使用 ar 工具(archive)

nowcode@nowcode:~/test01/calc$ ar rcs libcalc.a add.o div.o mult.o sub.o
nowcode@nowcode:~/test01/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.a
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o
3、使用

(1) 将 libcalc.a 复制到 library 下的 lib

nowcode@nowcode:~/test01/calc$ cp libcalc.a ../library/lib/
nowcode@nowcode:~/test01/calc$ cd ..
nowcode@nowcode:~/test01$ cd library
nowcode@nowcode:~/test01/library$ tree
.
├── include
│   └── head.h
├── lib
│   └── libcalc.a
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mult.c
    └── sub.c

(2)使用 gcc 编译 main.c 文件
关于gcc编译参数可以参考文章:Linux系统 gcc工作流程和gcc编译参数

nowcode@nowcode:~/test01/library$ gcc main.c -o app -I ./include/ -l calc -L./lib/
nowcode@nowcode:~/test01/library$ ./app
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667

三、动态库

1、命名规则
  • libxxx.so
      lib :前缀(固定)
      xxx :库的名字,自己起
      .so :后缀(固定)
    在Linux下是一个可执行文件
2、制作与使用

(1)gcc 获得 .o 文件,得到和位置无关的代码

nowcode@nowcode:~/test02/calc$ gcc -c -fpic add.c div.c mult.c sub.c
nowcode@nowcode:~/test02/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

(2)gcc 得到动态库

nowcode@nowcode:~/test02/calc$ gcc -shared add.o div.o mult.o sub.o -o libcalc.so
nowcode@nowcode:~/test02/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.so
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

(3)使用动态库

nowcode@nowcode:~/test02/calc$ cp libcalc.so ../library/lib/
nowcode@nowcode:~/test02/calc$ cd ..
nowcode@nowcode:~/test02$ cd library
nowcode@nowcode:~/test02/library$ tree
.
├── include
│   └── head.h
├── lib
│   └── libcalc.so
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mult.c
    └── sub.c
nowcode@nowcode:~/test02/library$ ./app
./app: error while loading shared libraries: libcalc.so: cannot open shared object file: No such file or directory
3、加载失败的原因
  • 静态库:GCC进行链接时,会把静态库中代码打包到可执行程序中
  • 动态库:GCC进行链接时,动态库的代码不会被打包到可执行程序中
  • 程序启动之后,动态库会被动态加载到内存中,通过ldd(list dynamic dependencies)命令检查动态库依赖关系
  • 如何定位共享文件呢?
      当系统加载可执行代码时候,能够知道其依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取绝对路径。对于elf格式的可执行文件,是 ld-linux.so 来完成的,它先后搜索elf文件的DT_RPATH段 ⟶ \longrightarrow 环境变量LD_LINRARY_PATH ⟶ \longrightarrow /etc/ld.so.cache文件列表 ⟶ \longrightarrow /lib/,/usr/lib目录找到库文件后载入内存
4、解决加载失败的方法
a. 配置环境变量DL_LIBRARY_PATH
(1)暂时配置
nowcode@nowcode:~/test02/library$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/nowcode/test02/library/lib
nowcode@nowcode:~/test02/library$ echo $LD_LIBRARY_PATH 
:/home/nowcode/test02/library/lib
nowcode@nowcode:~/test02/library$ ./app
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667
(2)用户级配置

打开.bashrc文件

nowcode@nowcode:~$ vim .bashrc

.bashrc文件最后加入下面语句

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/nowcode/Linux/lesson06/library/lib

在加入后,要运行一下.bashrc文件

nowcode@nowcode:~$ . .bashrc
(3)系统级配置

打开 /etc/profile文件

nowcode@nowcode:~/test02/library$ sudo vim /etc/profile

/etc/profile文件最后加入下面语句

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/nowcode/Linux/lesson06/library/lib

在加入后,要运行一下 /etc/profile文件

nowcode@nowcode:~/test02/library$ . /etc/profile
b. 处理/etc/ld.so.cache文件列表

打开/etc/ld.so.conf文件

nowcode@nowcode:~$ sudo vim /etc/ld.so.conf

/etc/profile文件加入下面语句

/home/nowcode/test02/library/lib

更新/etc/ld.so.cache文件列表

nowcode@nowcode:~$ sudo ldconfig
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CodeKwang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值