gpt4 book ai didi

linker - `-rpath-link` 和 `-L` 有什么区别?

转载 作者:行者123 更新时间:2023-12-03 12:26:53 26 4
gpt4 key购买 nike

男人为gold状态:

  -L DIR, --library-path DIR
Add directory to search path

--rpath-link DIR
Add DIR to link time shared library search path

bfd的男人 ld听起来有点像 -rpath-link用于递归包含的 sos。
ld.lld甚至没有将其列为参数。

有人可以为我澄清这种情况吗?

最佳答案

这是一个演示,适用于 GNU ld-L之间的区别和 -rpath-link ——
为了更好地衡量,-rpath-link 之间的差异和 -rpath .
foo.c

#include <stdio.h>

void foo(void)
{
puts(__func__);
}
bar.c
#include <stdio.h>

void bar(void)
{
puts(__func__);
}
foob​​ar.c
extern void foo(void);
extern void bar(void);

void foobar(void)
{
foo();
bar();
}
main.c
extern void foobar(void);

int main(void)
{
foobar();
return 0;
}
制作两个共享库, libfoo.solibbar.so :
$ gcc -c -Wall -fPIC foo.c bar.c
$ gcc -shared -o libfoo.so foo.o
$ gcc -shared -o libbar.so bar.o
制作第三个共享库, libfoobar.so这取决于前两个;
$ gcc -c -Wall -fPIC foobar.c
$ gcc -shared -o libfoobar.so foobar.o -lfoo -lbar
/usr/bin/ld: cannot find -lfoo
/usr/bin/ld: cannot find -lbar
collect2: error: ld returned 1 exit status
哎呀。链接器不知道去哪里解决 -lfoo-lbar . -L选项解决了这个问题。
$ gcc -shared -o libfoobar.so foobar.o -L. -lfoo -lbar
-Ldir选项告诉链接器 dir是目录之一
搜索解决 -lname 的库它给出的选项。它搜索 -L首先是目录,按命令行顺序;然后它搜索它的
配置的默认目录,按其配置顺序。
现在制作一个依赖于 libfoobar.so 的程序:
$ gcc -c -Wall main.c
$ gcc -o prog main.o -L. -lfoobar
/usr/bin/ld: warning: libfoo.so, needed by ./libfoobar.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libbar.so, needed by ./libfoobar.so, not found (try using -rpath or -rpath-link)
./libfoobar.so: undefined reference to `bar'
./libfoobar.so: undefined reference to `foo'
collect2: error: ld returned 1 exit status
哎呀又来了。链接器检测到 libfoobar.so 请求的动态依赖项
但不能满足他们。让我们拒绝它的建议 - try using -rpath or -rpath-link ——
看看我们可以用 -L 做什么和 -l :
$ gcc -o prog main.o -L. -lfoobar -lfoo -lbar
到现在为止还挺好。但:
$ ./prog
./prog: error while loading shared libraries: libfoobar.so: cannot open shared object file: No such file or directory
在运行时,加载器找不到 libfoobar.so .
那么链接器的建议呢?与 -rpath-link , 我们可以做的:
$ gcc -o prog main.o -L. -lfoobar -Wl,-rpath-link=$(pwd)
并且这种联系也成功了。 ( $(pwd) 表示“ P rint W orking D irectory”和当前路径)”和“副本” -rpath-link=dir选项告诉链接器,当它遇到一个输入文件时
请求动态依赖项 - 如 libfoobar.so - 它应该搜索目录 dir
解决它们。所以我们不需要用 -lfoo -lbar 指定这些依赖项不要
甚至需要知道它们是什么。它们是已经写入的信息 libfoobar.so动态版块:-
$ readelf -d libfoobar.so

Dynamic section at offset 0xdf8 contains 26 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libfoo.so]
0x0000000000000001 (NEEDED) Shared library: [libbar.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
...
...
我们只需要知道可以找到它们的目录,无论它们是什么。
但这是否给了我们一个可运行的 prog ?
$ ./prog
./prog: error while loading shared libraries: libfoobar.so: cannot open shared object file: No such file or directory
不。和之前的故事一样。那是因为 -rpath-link=dir为链接器提供信息
加载器需要解决 prog 的一些动态依赖项
在运行时 - 假设它在运行时仍然为真 - 但它不会将该信息写入 prog 的动态部分.
它只是让链接成功,而无需我们详细说明所有递归动态
-l 链接的依赖关系选项。
在运行时, libfoo.so , libbar.so - 确实 libfoobar.so ——
很可能不是现在的位置 - $(pwd) - 但装载机可能能够找到它们
其他方式:通过 ldconfig 缓存或设置
LD_LIBRARY_PATH环境变量,例如:
$ export LD_LIBRARY_PATH=.; ./prog
foo
bar
rpath=dir为链接器提供与 rpath-link=dir 相同的信息
并指示链接器将该信息烘焙到动态部分
输出文件。让我们试试:
$ export LD_LIBRARY_PATH=
$ gcc -o prog main.o -L. -lfoobar -Wl,-rpath=$(pwd)
$ ./prog
foo
bar
都好。因为现在, prog包含 $(pwd) 的信息是运行时搜索
它所依赖的共享库的路径,我们可以看到:
$ readelf -d prog

Dynamic section at offset 0xe08 contains 26 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libfoobar.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [/home/imk/develop/so/scrap]
... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
该搜索路径将在 LD_LIBRARY_PATH 中列出的目录之后尝试,如果设置了,并且在系统默认值之前 - ldconfig -ed 目录,加上 /lib/usr/lib .

关于linker - `-rpath-link` 和 `-L` 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49138195/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com