📝前言:
这篇文章我们来讲讲Linux------动静态库的使用
🎬个人简介:努力学习ing
📋个人专栏:Linux
🎀CSDN主页 愚润求学
🌄其他专栏:C++学习笔记,C语言入门基础,python入门基础,C++刷题专栏
这里写目录标题
一,什么是库
基本概念:
- 库是写好的现有的,成熟的,可以复用的代码
- 静态库:
.a[Linux]、.lib[windows]
- 动态库:
.so[Linux]、.dll[windows]
- 库的命名规则,前缀
lib
+NAME
+ 后缀库类型
(其中真正的库名是NAME
)- 示例:名字为
c
的静态库:libc.a
、.a
后面还可以跟其他后缀
- 示例:名字为
动静态库的形成:
- 动静态库,通常都是由
.o
文件打包来的 .o
文件是编译后形成的可重定向目标文件
二,静态库
认识静态库
- 静态库在链接的时候,把用到的库函数的代码链接(拷贝)到可执行文件中,后续运行时不再需要静态库
形成静态库
多个.o
文件打包成静态库示例:
Makefile文件:
bash
1 libmyc.a: mystdio.o mystring.o
2 ar -rc $@ $^
3 %.o:%.c
4 gcc -c $<
5 .PHNOY:clean
6 clean:
7 rm -rf *.a *.o
8
ar
:归档打包,打包完以后,未来不用解包,可以直接使用gcc/g++
链接
运行示例:
查看库的详细信息
ar -tv 库
可以查看库
的信息:
使用静态库
源文件链接库形成可执行文件
使用gcc
链接:
- 选项
-l
:接要链接的库名称 - 选项
-L
:接要找的库所在的目录路径(不带-L
系统去默认路径下找库) - 选项
-I
:接要找的头文件所在的目录路径(不带-I
,系统去默认路径下找头文件,并且会在当前目录找)
使用静态库链接,形成可执行文件示例:
cpp
gcc -o test test.c -I ./ -L ./ -l myc
上面这种写法就是全链路写法。一旦静态库链接成功,本质已经把对应的库函数代码拷贝给了可执行文件,后续无序找库,一定能运行成功。
- 当动静态库同时存在的时候,
gcc
会默认使用动态库。如果非要使用静态库,需要带-static
选项(带了这个选项,就必须存在对应的静态库)
三,动态库
认识动态库
- 动态库(
.so
):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。 - 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。
- 动态库是运行时链接,运行时还需要依赖动态库。不像静态库一旦编译链接成功以后就一定可以运行成功。
形成动态库
- 动态库用
gcc
打包, 带-shared
选项 - 形成的
.o
文件要带-fPIC
选项(用于生成位置无关代码,动态库的.o
文件要求)
Makefile文件:
bash
1 libmyc.so: mystdio.o mystring.o
2 gcc -o $@ $^ -shared
3 %.o:%.c
4 gcc -fPIC -c $<
5 .PHONY:clean
6 clean:
7 rm -rf *.so *.o

使用动态库
同样有三种使用方法:
bash
// 场景1:头⽂件和库⽂件安装到系统路径下(不带 -I 和 -L 都去系统路径找)
gcc main.c -lmystdio
// 场景2:头⽂件和库⽂件和我们⾃⼰的源⽂件在同⼀个路径下(不带 -I 头文件回去当前目录找)
gcc main.c -L. -lmymath // 从左到右搜索-L指定的⽬录
// 场景3:头⽂件和库⽂件有⾃⼰的独⽴路径(都不在当前路径,找不到就要指明路径)
gcc main.c -I头⽂件路径 -L库⽂件路径 -lmymath
示例:
但是,为什么编译链接,形成可执行文件后,还是运行不了,说没找到?
查看链接关系
ldd + 可执行文件名
,可查看链接的动态库
我们发现,libmyc.so
是not found
。这是因为,我们前面提供的-L
只是告诉了编译器,但是系统任然不知道我们的动态库在哪里。
解决方法如下:
添加动态库
- 直接把库拷贝一份到系统默认找库的文件夹,一般是:
/usr/lib、/usr/local/lib、/lib64
(但是这不推荐,会污染系统目录) - 在系统默认拷贝的文件夹里面添加对应动态库的软链接
- 更改环境变量:
LD_LIBRARY_PATH
(这个变量有可能为空,我们可以自行export
导入) - 配置
/etc/ld.so.conf.d/
:在这个目录下新建一个任意名称的配置文件,然后再文件里面放动态库的路径(系统会默认去里面找)【但是这个好像写不进去】- 改完这个配置以后,
ldconfig
可以重新加载配置,才能生效
- 改完这个配置以后,
我们使用解决方法3
,添加后,运行程序:
cpp
export LD_LIBRARY_PATH="/home/tr/code/Linux_learn/library_un:$LD_LIBRARY_PATH"
:
:用来分割路径$LD_LIBRARY_PATH
:获取原来的环境变量值,然后再次基础上添加- 建议使用绝对路径
此时就链接上了,a.out
运行结果:
把头文件添加到默认路径
- 同样,头文件有默认搜索的路径:
/usr/include
。我们可以拷贝文件进去,或者建立软链接 - 设置
CPATH
环境变量(针对 C 语言)或者CPLUS_INCLUDE_PATH
环境变量(针对 C++) - 但是更建议:
-I
四,使用外部库
库的安装,就是把库对应的文件拷贝到了指定(默认搜索)的目录下
这里我们安装一个ncurse
库
我们可以查看一下/usr/lib
或 /usr/include
,看看有没有这个外部库的库文件和头文件
/usr/include
里面的
我们简单使用一下(参考文章:ncurse编程指南),在屏幕左上角打印Hello, World
:
cpp
1 #include <ncurses.h>
2
3 int main()
4 {
5 initscr(); // 初始化屏幕,默认stdscr
6 printw("Hello World");// 与printf相似但是打印到虚拟窗口stdscr
7
8 refresh();// 需要刷新才能显示到屏幕上
9 getch(); // 等待用户输入
10 endwin(); // 关闭窗口
11 return 0;
12 }
编译链接,gcc -o test2 test2.c -lncurses
,并运行:
🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!