静态库
1、概念
静态库 是在可执行程序运行之前就已经加入到执行代码中,成为执行程序的一部分;静态库的后缀一般是 .a
作为后缀。
2、创建静态库
创建一个静态库,或者是要将目标代码
加入到已经存在的静态库中,可以使用如下命令:
ar rcs libxxx.a hello.o
ar 是GNU 归档工具,rcs 表示(replace and create)
3、应用程序中使用静态库
使用gcc 的 -l 选项来指定静态库,使用 -L 选项来指定库文件的搜索路径。
样例
如果我们使用 目录/home/username/public 下 libabc.a
静态库,则需指定静态库的目录 -L/home/username/public
(注意 -L
后面是没有空格的),指定静态库 -labc
。
注意:
因为linux的gcc 默认链接动态库,但动态库不存在时,才链接静态库,若是需要强制指定静态库需要指定选项 -static
。
4、静态库链接时搜索路径顺序:
- ld回去找GCC命令中的参数
-L
- 再去找GCC的环境变量
LIBRARY_PATH
- 再找内定目录
/lib
/usr/lib
/usr/local/lib
这是当初compiler gcc时写在程序内的动态链接时、执行时搜索路径顺序
共享库
1、概念
共享库 是在程序执行期间需要调用到共享库的时候才加载到内存里面,可以被多个程序共享使用;每个共享库都有三个文件名:real name
、soname
和 linker name
。
//real name
-rwxr-xr-x 1 root root 11511640 libavcodec.so.57.24.102
//soname
lrwxrwxrwx 1 root root libavcodec.so.57 -> libavcodec.so.57.24.102
//linker name
lrwxrwxrwx 1 root root libavcodec.so -> libavcodec.so.57.24.102
real name:真正的库文件,包含库文件的完整版本号
soname:符号链接的名字,只包含共享库的主版本号(主版本号相同,函数的接口是一致的);因此应用程序的.dynamic
段只记录共享库的soname,只要soname一致,这个共享库就可以用。
linker name:在编译链接时使用,gcc 的-L选项应该指定linker name
所在目录
2、创建动态库
简单的创建动态库使用如下命令:
gcc -shared -fPIC abc.c -o libabc.so
3、加载共享库
链接路径
连接时找不到某一个函数,出现xxxxx undefined
,应该就是连接时找不到相应的动态库,连接时动态库的路径如下:
- 默认路径是:
/lib
,/usr/lib/
,/usr/local/lib
-
-L
: 指定连接时动态库的路径 -
LD_LIBRARY_PATH
:指定连接路径
运行路径
运行应用程序时出现 error while loading shared libraries
,则是加载时找不到相应的动态库
- ELF可执行文件中动态段中
DT_RPATH
所指定的路径。这实际上是通过一种不算很常用,却比较实用的方法所设置的:编译目标代码时,可以对gcc加入链接参数-Wl,-rpath
指定动态库搜索路径; - 环境变量
LD_LIBRARY_PATH
指定的动态库搜索路径; -
/etc/ld.so.cache
中所缓存的动态库路径(如果支持ld.so.cache的话)。这可以通过修改配置文件/etc/ld.so.conf
中指定的动态库搜索路径来改变; - 默认的动态库搜索路径/lib;
- 默认的动态库搜索路径/usr/lib。
样例
1、创建一个目录 calc
mkdir /home/username/calc
2、创建1个c文件和1个.h,实现加减乘除
文件 calc.c
int add(int a, int b)
{
return a+b;
}
int sub(int a, int b)
{
return a-b;
}
int mul(int a, int b)
{
return a*b;
}
int dive(int a, int b)
{
return a/b;
}
calc.h
#ifndef CALC_H_
#define CALC_H_
int add(int a, int b);
int sub(int a, int b);
int dive(int a, int b);
int mul(int a, int b);
#endif
3、制作静态库
gcc -c calc.c -o calc.o
ar rcs libcalc.a calc.o
4、制作共享库
gcc -c -fPIC calc.c
gcc -shared -Wl,-soname,libcalc.so.1 -o libcalc.so.1.10 calc.o
5、设置共享库加载路径
- 打开共享库路径配置文件:
sudo vi /etc/ld.so.conf
- 最后一行添加mycal路径:
/home/username/calc
- 更新共享库加载路径:
sudo ldconfig -v
- 此时可以看到自动创建出来了soname
libcalc.so.1
- 手动添加link name:
ln -s libcalc.so.1.10 libcalc.so
6、测试
编写测试文件main.c,分别去链接静态库和共享库,进行测试
文件 main.c
#include <stdio.h>
#include "common.h"
int main(void)
{
printf("%d\n", add(5, 3));
return 0;
}
链接动态库: gcc main.c -o main -Wl,-rpath=./ -lcalc
网友评论