在ld.so(8) 的手册页中,它说
解析库依赖项时,动态链接器首先检查每个依赖项字符串以查看它是否包含斜杠(如果在链接时指定了包含斜杠的库路径名,则会发生这种情况)。如果找到斜线,则依赖字符串被解释为(相对或绝对)路径名,并使用该路径名加载库。
如何gcc
链接到带有斜杠路径的库?我已经尝试过,-l
但这似乎只适用于用于搜索各种路径的库名称,而不是路径参数本身。
一个后续问题:当以这种方式链接到相对路径时,相对路径是什么(例如包含二进制文件的目录或运行时的工作目录)?
我在搜索时找到的所有链接指南都使用RPATH
、LD_LIBRARY_PATH
和RUNPATH
. RPATH
已弃用,大多数讨论不鼓励使用LD_LIBRARY_PATH
. RUNPATH
以 开头的路径$ORIGIN
允许链接到相对路径,但它有点脆弱,因为它可以被LD_LIBRARY_PATH
. 我想知道相对路径是否会更健壮(因为我找不到任何讨论这个的东西,我猜不是,可能是因为路径是相对于运行时目录的)。
如果我们(暂时)忽略
gcc
问题的或链接部分,而是patchelf
在 linux 系统上修改二进制文件我们现在有一个带有相对路径库的二进制文件,如果存在合适的目录,其中存在
libhello.so.1
文件我们发现路径是相对于进程的工作目录的,这就带来了各种各样的问题,尤其是安全 问题。这可能有一些生产用途,也许可以测试不同版本的库。编译两个不同的二进制文件可能会更简单,或者
patchelf
在必要的库中编译,而不需要复杂的相对工作目录。编译步骤
libhello
只有一个helloworld
电话并通过编译
并且
hello
进行调用的那个helloworld
是通过编译的没有补丁
事后看来,修改
gcc
命令以使用相对目录路径:以正常方式编译库,然后根据需要使用
patchelf
.您可以通过将选项传递给链接器来做到这一点。例如,要从 ncurses 的构建目录(依赖于未安装的库)运行测试程序,我使用这样的选项(在 gcc 命令行中):
它嵌入了一个相对路径名。相同的选项可以嵌入绝对路径名:
这样做对于本地测试很有用,但由于各种原因,对于在系统上安装没有用。Debian 有一个反对它的政策,可以追溯到 1990 年代,尽管很少有连贯的讨论(例如,参见收集一些信息的RPATH 问题)。