个人主页:Lei宝啊
愿所有美好如期而遇
目录
前言
库?
为什么要使用库
静态库
静态库的制作和使用
动态库
动态库的制作和使用
四种方法:
直接将库拷贝(安装)到系统路径中
配置环境变量
软链接
添加配置文件
动态库和静态库同时存在
总结
前言
首先提到,我们用过库吗?C语言,C++其实我们一直都在使用库,你一定听说过C标准库,博主这里介绍动静态库使用的是云服务器,在云服务器上,默认安装的是动态库,静态库默认是没有安装的,我们默认编译程序,链接的是动态库,如果想要链接静态库,需要安装,并加上static选项,我们举例来说明:
首先,我们来安装C静态库(博主已经安装了)
sudo yum install glibc-static
接着就是C++静态库
sudo yum install libstdc++-static
我们随便写一个C文件,然后先进行编译:
我们使用gcc编译器,默认就是使用动态库进行链接,接着我们使用ldd查看可执行程序链接的是什么库,我们可以看到链接的是libc.so.6这个库,查看库的名字,就是去掉前缀lib,去掉后缀so.6,这个库的名族就叫c,也就是我们的C标准库,而在linux下,.so是动态库的后缀,.a是静态库的后缀。
接着我们对这个文件进行静态编译:
gcc 文件名 -static
我们可以看到,ldd已经无法查看这个文件,那么我们使用file指令来查看这个文件,可以清楚的看到statically linked,这就是静态链接的意思。
库?
为什么要使用库
我们先来准备一些文件:
我们实现了加减乘除。
如果说,这些文件要给别人使用,那么如果没有库,他们会怎么使用?是这样:
当然,我们也可以这样:
如果说有更多的文件呢?成百上千个的话,难道一个个的敲吗?所以我们需要库,库就是将这些.c文件编译后形成的.o文件打包乘一个文件,然后我们进行使用。
静态库
静态库的制作和使用
我们先新建一个目录,将所有.c和.h文件拷贝进来,接下来我们将制作一个静态库。(在我们给交付别人时,当然是不想给他发源文件的,但是我们可以给他发.o文件和头文件,他照样可以使用,但是文件太多别人用着也麻烦,所以我们就将这些文件打包成库)
ar -rc 文件
我们将这些文件一次性打包后并发布:
上面第一行代码,意思是将.c文件全部替换成.o文件,wildcard意思是寻找所有.c文件,下面的%.o:%.c和下面一行代码意思是寻找所有.c文件编译成,o文件。
output就是我们要进行的打包操作。
我们来看make后效果:
接着我们进行打包:
假设我们有个user目录,将这个包给给用户,用户有个test.c文件,那么用户怎么使用呢?
首先进行解包:
tar -zxf 包名
我们在进行与静态库的链接时,如果我们的库和头文件不在当前目录,头文件路径需要使用-I(大i)指明,库路径需要使用-L指明,同时需要使用-l(小L)指明链接的库的名字。
或者指明头文件路径后,给出库路径和库的全称(不要去掉前后缀),这样就相当于给了路径和库名,也是可以的。
动态库
动态库的制作和使用
生成动态库需要的.o文件需要进行特殊处理:
我们加上-fPIC选项,同时生成动态库不需要其他指令,使用gcc就可以,加上-shared选项。
下面这种情况我们怎么办?同时,为什么静态库这样链接后,运行时没有这样的报错?
四种方法:
头文件搜索路径:
- 当前路径
- 系统默认路径:/usr/include
库搜索路径:
- 由环境变量 (LD_LIBRARY_PATH) 辅助搜索(动态库)
- 系统指定路径:/lib64 或者 /usr/lib64
直接将库拷贝(安装)到系统路径中
我们这样做,在生成可执行程序时,也不需要指定库路径,在执行时,当然也不需要,但是,非官方库不要安装在系统目录下。
配置环境变量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:我们的路径
但是这样做的话只是临时添加,当我们再次登录时,环境变量从配置文件读取,我们还是没有永久添加。
我们可以这样做:
我们可以在这里面修改,下次登录时环境变量读取配置文件,我们也就不用再去添加了。
软链接
现在我们对库进行软链接,并安装在系统目录下。
删除:
添加配置文件
/etc/ld.so.conf.d/
我们添加一个后缀为.conf的文件,将库路径写进文件中即可。
注意:需要提权打开系统文件,否则无法进行写入
但是我们发现还是找不到,这是因为我们修改了配置文件,操作系统并不清楚,所以我们需要执行一条命令来使刚刚的命令生效
动态库和静态库同时存在
如果动静态库同时存在,那么gcc默认使用的是哪个库呢?
很显然,两者同时存在时,gcc默认选择使用动态库。
如果我们一定要静态链接,需要加上-static选项:
如果我们只提供静态库,那么他只能静态链接,但是整体不一定是静态链接,只是我们这个库局部静态链接。
如果我们只提供动态库,却非要静态链接,那么连接器就会报错:
总结
制作静态库 ar -rc -o 文件名 一系列.o文件
制作动态库 gcc -shared -o 文件名 一系列.o文件
使用静态库 gcc main.c -I(大i) 头文件路径 -L库路径 -l(小l)库名
或者(头文件在当前路径) gcc main.c 路径/库
使用动态库 执行可执行程序时,需要四种方法,或者直接gcc main.c 路径/库(.h 在 ./)