使用相对路径链接库是否属于错误或未定义行为?
问题分析与解答
这种链接方式不算未定义行为,但属于不规范的链接做法,会直接导致依赖解析的连锁问题,下面具体拆解:
1. 为什么ldd -r A会提示B找不到?
-L../dir2只是链接阶段给链接器指定的临时搜索路径,它不会被写入共享库A的动态依赖元数据中。运行时动态链接器(以及ldd工具)只会默认搜索系统标准库路径和LD_LIBRARY_PATH环境变量里的路径,自然找不到不在这些路径里的B。
2. 链接C时用-Wl,-rpath-link=../dir2的问题
-rpath-link是链接C时的临时辅助路径,作用是帮链接器找到A所依赖的B,从而完成C的链接过程,但这个路径不会被写入C的动态依赖信息。这意味着:
- 链接C时能成功,但运行C的时候,动态链接器还是会找不到B,因为C本身没记录B的路径,A也没记录。
- 这种做法相当于把依赖查找的问题推迟到了运行阶段,不是根本解决办法。
3. 正确的解决方式
- 构建共享库A时,直接把B的相对路径写入A的动态依赖元数据:
这样运行时,动态链接器会自动从A所在目录的上级目录下的dir2中查找B,# Linux环境下,$ORIGIN表示当前库所在的目录 gcc -shared -fPIC -o A A.c -L../dir2 -lB -Wl,-rpath='$ORIGIN/../dir2'ldd -r A也能正常找到B。 - 链接C时,只要A已经正确设置了rpath,只需要执行:
不需要额外添加gcc -shared -fPIC -o C C.c -L../dir1 -lA-rpath-link参数,链接器会通过A的rpath找到B,运行C时也能正常解析所有依赖。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

