【Linux】动静态库的使用

📝前言:

这篇文章我们来讲讲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文件:

  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,系统去默认路径下找头文件,并且会在当前目录找)

使用静态库链接,形成可执行文件示例:

gcc -o test test.c -I ./ -L ./ -l myc

上面这种写法就是全链路写法。一旦静态库链接成功,本质已经把对应的库函数代码拷贝给了可执行文件,后续无序找库,一定能运行成功。

  • 当动静态库同时存在的时候,gcc会默认使用动态库。如果非要使用静态库,需要带-static选项(带了这个选项,就必须存在对应的静态库)

三,动态库

认识动态库

  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。
  • 动态库是运行时链接,运行时还需要依赖动态库。不像静态库一旦编译链接成功以后就一定可以运行成功。

形成动态库

  • 动态库用gcc打包, 带-shared选项
  • 形成的.o文件要带-fPIC选项(用于生成位置无关代码,动态库的.o文件要求)

Makefile文件:

  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

在这里插入图片描述

使用动态库

同样有三种使用方法:

// 场景1:头⽂件和库⽂件安装到系统路径下(不带 -I 和 -L 都去系统路径找)
gcc main.c -lmystdio

// 场景2:头⽂件和库⽂件和我们⾃⼰的源⽂件在同⼀个路径下(不带 -I 头文件回去当前目录找)
gcc main.c -L. -lmymath // 从左到右搜索-L指定的⽬录

// 场景3:头⽂件和库⽂件有⾃⼰的独⽴路径(都不在当前路径,找不到就要指明路径)
gcc main.c -I头⽂件路径 -L库⽂件路径 -lmymath

示例:
在这里插入图片描述
但是,为什么编译链接,形成可执行文件后,还是运行不了,说没找到?

查看链接关系

ldd + 可执行文件名,可查看链接的动态库
在这里插入图片描述
我们发现,libmyc.sonot found。这是因为,我们前面提供的-L只是告诉了编译器,但是系统任然不知道我们的动态库在哪里。

解决方法如下:

添加动态库

  1. 直接把库拷贝一份到系统默认找库的文件夹,一般是:/usr/lib、/usr/local/lib、/lib64(但是这不推荐,会污染系统目录)
  2. 在系统默认拷贝的文件夹里面添加对应动态库的软链接
  3. 更改环境变量: LD_LIBRARY_PATH(这个变量有可能为空,我们可以自行export导入)
  4. 配置/etc/ld.so.conf.d/ :在这个目录下新建一个任意名称的配置文件,然后再文件里面放动态库的路径(系统会默认去里面找)【但是这个好像写不进去】
    • 改完这个配置以后,ldconfig 可以重新加载配置,才能生效

我们使用解决方法3,添加后,运行程序:

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

  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,并运行:
在这里插入图片描述


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

愚润泽

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

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

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

打赏作者

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

抵扣说明:

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

余额充值