1.动静态库概念
我们平常使用的C\C++语言标准标准库,我们只是包含了库的头文件就可以使用,要想使用库的内容,必然要使我们编写的代码和库内容进行关联,我们的源文件变为可执行文件要经过预处理-编译-汇编-链接阶段。其中的链接阶段,有两种关联方式,一是动态链接(动态库),而是将静态库的相应代码加载的可执行文件中(静态库)
- 静态库(.a):程序在编译链接阶段的时候把库内的代码链接可执行文件中。程序运行时就不需要静态库。
- 动态库(.so):程序在运行时才去链接动态库的代码,多个程序共享库中代码。
2.如何编写静态库
首先需要编写头文件,在头文件内声明函数。然后在.c文件内完成对应函数方法的编写。下面给出累加函数的.h、.c文件。
#pragma once
#include <stdio.h>
extern void sum(int from, int to);
#include "mysum.h"
void sum(int from, int to)
{
int sum =0;
int i = from;
for (; i <= to; i++)
{
sum += i;
}
printf("%d\n", sum);
}
使用linux命令gcc -c mysum.c -o mysum.o生成二进制.o文件然后使用ar进行打包,将.o文件打包为静态库。ar -rc (lib前缀+静态库名+.a后缀) 所有需要打包的的.o文件。(实际上有.o文件和.h文件就就可以给别人使用了,但是使用ar可以将多个.o文件进行打包方便使用)
ar -rc libmya.a mysum.o
为了方便管理我们通常创建一个文件用于存放.h文件夹和.a静态库。例如
mkdir -p out/lib
mkdir -p out/include
cp -rf *.h out/include
cp -rf *.a out/lib
3.如何使用静态库
3.1 拷贝到库内
gcc默认的头文件搜索路径: /usr/include
库文件默认搜索路径: /lib64 or /usr/lib64
将对应的.h文件放入/usr/include,.a静态库放入/lib64 or /usr/lib64
mv .h文件 /usr/include
mv .a静态库 /lib64 or /usr/lib64
使用gcc编译发现还是无法正常使用。这是因为我们放入的库和.h头文件是第三方提供的,所以我们需要指明需要使用的静态库名下面给出示例: gcc 需要编译的源文件 -l静态库名(需要注意的是静态库名是去掉前缀lib去掉后缀.o)
gcc main.c -lmya
我们这样将库拷贝到系统的默认路径下,就叫做库的安装(不推荐这样做,我们写的库没有通过安全性认证)
3.2 指定静态库路径
我们还可以通过指定我们静态库的文件路径然后给出静态库名,指定头文件路径使用
gcc 源文件名 -I 头文件路径 -L 静态库路径 -l静态库名
gcc main.c -I ./out/include/ -L ./out/lib/ -lmya
4.如何编写动态库
同样使用gcc添加-c选项编译为.o文件不够还加上了-fPIC选项(表示形成一个与位置无关的二进制文件)
gcc -c -fPIC mysum.c -o mysum_s.o
同样可以将.o文件进行打包,不同的是直接使用gcc即可打包
gcc -shared -o libmyso.so mysum_s.o
5. 如何使用动态库
5.1拷贝到库内
前面将静态库拷贝到库文件默认搜索路径的方法对动态库也同样适用。(需要注意的是当我们既有静态库又有动态库,gcc会默认使用静态库,即静态库优先原则,如果非要使用静态库,可以使用-static选项,只有静态库时也是会使用静态库的)
5.1配置环境变量
动态库的使用还可以配置环境变量,动态库的使用是在运行时将动态库加载到内存中使用的,我们光使用编译器没有办法告知系统动态库的位置,所以我们需要将动态库的路径添加到环境变量中。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:(填写你的动态库的绝对路径在动态库文件夹下使用pwd命令查看路径)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/an/test/CSoA/out/lib
导入完成后可以使用echo $LD_LIBRARY_PATH查看是否导入成功(这样导入只在本次登录生效,如果退出登录,环境变量会重新加载,覆盖我们导入的环境变量)
如果想要环境变量不被替换可以在/etc/ld.so.conf.d创建.conf后缀文件(需要root权限)
然后将动态库的绝对路径写入.conf后缀的文件内。
使用sudo ldconfig命令更新环境变量
5.2 创建软链接
上面两个方法都有一点麻烦,下面介绍一种比较简单的方法
使用命令sudo ln -s 静态库绝对路径(不能使用相对路径) /lib64 or /usr/lib64/(给软链接取一个名字例如libmyso.h)。