静态库
静态库在程序的链接阶段被复制到了程序中
静态库的命名规则
Linux: libxxx.a
lib:前缀(固定)
xxx:库的名字(自定义)
.a:后缀(固定)
Windows: libxxx.lib
静态库的制作
1. gcc获得 .o 文件
2. 将 .o 文件打包,使用 ar 工具(archive)
ar rcs libxxx.a xxx.o xxx.o
r - 将文件插入备存文件中
c - 建立备存文件
s - 索引
静态库的使用
工程文件目录如下:
首先先制作静态库
//-I ../include/ 表示进入include中寻找head.h,否则会找不到head.h这个文件
gcc -c add.c sub.c mult.c div.c -I ../include/
利用以上生成的文件生成静态库:
ar rcs libsuanshu.a add.o div.o mult.o sub.o
将生成的静态库放入到lib路径下:
mv libsuanshu.a ../lib/
使用此静态库:
//-l suanshu 指定库suanshu
gcc main.c -o app -I ./include/ -L ./lib/ -l suanshu
动态库
动态库在程序运行时由系统动态加载到内存中供程序调用
动态库的命名规则
Linux: libxxx.so,是一个可执行文件
lib:前缀(固定)
xxx:库的名字(自定义)
.so:后缀(固定)
Windows: libxxx.dll
动态库的制作
1. gcc获得 .o 文件,得到和位置无关的代码
gcc -c -fpic/-fPIC a.c b.c
2. gcc得到动态库
gcc -shared a.o b.o -o libcalc.so
动态库的使用
工程文件目录如下:
首先制作动态库:
gcc获得 .o 文件,得到和位置无关的代码
gcc -c -fpic add.c div.c mult.c sub.c
gcc -shared add.o div.o sub.o mult.o -o libcalc.so
将生成的动态库放入到lib路径下:
cp ../calc/libcalc.so ./lib/
使用此动态库:
**生成可执行文件main:**
gcc main.c -o main -I include/ -L lib/ -l calc
直接这样使用会报错,原因是找不到对应的动态库
以下是解决方法:
定位共享库文件:
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是由ld-linux.so来完成的,它先后搜索elf文件的 DT_RPATH段—>环境变量LD_LIBRARY_PATH-> /etc/ld.so.cache文件列表->/lib/,/usr/lib目录找到库文件后将其载入内存。
1.可以通过设置环境变量解决问题,这里有两种方法
这种方法是临时的,只在当前终端生效,再打开其他终端使用仍会报错
//后面是动态库路径
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:/home/.....
这里有两种永久的解决方法:一种是用户级别的,一种是系统级别的
用户级别:
编辑bashrc文件
vim .bashrc
在最后一行添加:
//后面是动态库路径
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:/home/.....
保存并退出后要使其生效:
source .bashrc
系统级别:
编辑profile文件:
sudo vim /etc/profile
在最后一行添加:
//后面是动态库路径
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:/home/.....
保存并退出后要使其生效:
source /etc/profile
注意:如果之前配置过用户级别,要重写打开一个新的终端进行系统级别的配置,不然可能会出现错误
2.也可以配置/etc/ld.so.cache解决问题
不能直接编辑这个文件,因为里面都是二进制数据
打开下面这个文件
sudo vim /etc/ld.so.conf
然后直接在文件里面添加路径
/home/.....
更新:
sudo ldconfig