1. 问题描述
目录结构如下:

编译build.sh脚本为:
gcc main.c -L. -ltlcpsocket -o main
编译后
运行可执行程序main,提示找不到动态链接库

默认情况下Linux系统到/lib或 /lib64下寻找链接库,如果连接库在这两个地方没有那么就会出现这个问题,即便我们的动态链接库与可执行程序位于同一个目录内。
我们使用gcc的-L参数指定了编译时的连接库所在目录位置,因此程序可以顺利编译。
在运行时,程序启动时需要加载动态链接库,上述问题就是在运行时找不到链接库导致。
2. 查看程序链接库
通过ldd查看可执行程序链接库
ldd [可执行程序名称]
例如:
可以看到这里的libtlcpsocket.so链接库提示没有找到,其几个链接库都找到对应的内存地址。
通过readelf查看可执行程序链接库详细情况
readelf -d [可执行程序]

可以看到这里的链接库都是没有路径的只有链接库名称。
3. 解决方案
gcc设置添加了运行时的链接库查询位置,使用 **-Wl,-rpath,**参数
gcc main.c -Wl,-rpath,'$ORIGIN'/. -L. -ltlcpsocket -o version
注意:
-Wl,-rpath,后的路径为$ORIGIN+.,表示./.,$ORIGIN代表了可执行文件所在的地址,程序在编译时该符号会保留在可执行文件,运行时替换为具体路径。[ 1 ] ^{[1]}[1]
编译后我们再通过ldd 和 readelf查看
可以看到ldd提示已经可以找到所有的链接库。
在readelf中增加了RUNPATH条目表示运行时动态库的路径。

4. 参考文献
[1]. csdn . 指定运行时动态库搜索位置 . 元口 . 2020.09 . https://blog.csdn.net/qq_41230365/article/details/108721527
[2]. 简书 . 使用rpath解决指定动态库链接目录问题 . 鱼大鱼 . 2019.11 . https://www.jianshu.com/p/83503c0c4d3d
版权声明:本文为q1009020096原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。