对于动态库,GCC进行链接时,动态库的代码不会被打包到可执行程序中。程序启动后,动态库会被动态加载到内存中,通过ldd(list dynamic dependencies)命令检查动态库依赖关系。
命名规则:
- Linux:libxxx.so
- lib:前缀(固定)
- xxx:库的名字
- .so:后缀(固定)
- 在Linux下是一个可执行文件
- Windows:libxxx.dll
动态库的制作:
- gcc得到.o文件,得到和位置无关的代码
- Linux命令为gcc -c -fpic/-fPIC a.c b.c
- gcc得到动态库
- Linux命令为gcc -shared a.o b.o -o libcalc.so
会生成libcalc.so文件
动态库的使用:
假设文件目录如下
使用命令
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目录找到库文件后将其载入内存。
改变环境变量LD_LIBRARY_PATH
解决方法一:
要使动态载入器能够找到动态库文件,需要为其配置环境变量,命令如下:
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:动态库的绝对路径
$用于获取原来LD_LIBRARY_PATH环境变量的内容,再把你的动态库路径拼接上去即可。
解决方法二(用户级别):
修改.bashrc文件,在文件最后加上
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:动态库的绝对路径
source .bashrc 或 . .bashrc 使其生效
解决方法三(系统级别):
sudo vim /etc/profile
在最后加上
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:动态库的绝对路径
source .bashrc 或 . .bashrc 使其生效
改变/etc/ld.so.cache文件
解决方法:
vim /etc/ld.so.conf
把动态库绝对路径复制进去
不建议在动态库文件放在/lib/, /usr/lib目录,因为其中有很多系统库函数。