为什么 -r 选项(可重定位)使 ld 找不到任何库?
使用 GNU ld 2.21 运行 Debian/Linux x86_64。
很简单,如果我链接
ld -o main main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
It 有效,但是当我链接
ld -r -o main1.o main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
It 抱怨
ld: cannot find -lc
ld: cannot find -lm
时,我实际上并没有尝试以这种方式编译代码,而是试图弄清楚为什么其他人的测试是否存在库不存在在职的。 (因此我不太明白ld
发生了什么......通常我只是使用GCC来链接)
为什么告诉ld
以可重定位的方式链接使它成为可能突然找不到库了? 之外我还应该做什么
ld -r -lm
如果我只是想测试 -lm
是否存在,除了让它找到该库
?如果您想查看我正在处理的源代码,可以在这里下载:https://github.com /jeremysalwen/ESPS (注意,第一次提交是原始源代码,后续的都是我个人所做的更改。)
Running Debian/Linux x86_64 with GNU ld 2.21.
Quite simply, if I link with
ld -o main main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
It works, but when I link with
ld -r -o main1.o main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
It complains
ld: cannot find -lc
ld: cannot find -lm
I'm not actually trying to compile code this way, but rather I'm trying to figure out why someone else's test to see if a library exists is not working. (Thus I don't really understand what's going on with ld
... usually I just use GCC to link)
Why would telling ld
to link in a relocatable fashion make it suddenly unable to find libraries? If I just want to test that -lm
exists, what should I do besides
ld -r -lm
so that it will find the library?
If you want to see the source that I'm dealing with, you can download it here: https://github.com/jeremysalwen/ESPS (note, that the first commit is the original source code, and the subsequent ones are changes I have personally made.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
MacOS X
在 MacOS X 上,
ld
的手册页对-r
选项非常明确:因此,如果您使用的是 MacOS X,问题在于
-lm
不是 Mach-O 目标文件,-lc
也不是。但是,理论上,如果您有目标文件main.o
、obj1.o
和obj2.o
并且您这样做:那么它可能会起作用。在实践中,它不会,并且在您得到的错误中:
但是,运行:
加载程序没有任何抱怨。
Linux
在 Linux 上,
ld
的手册页不太明确,但表示:从字里行间看,这也获取目标文件并将它们转换为目标文件;它不会添加库。如果您考虑一下,不会创建包含对库的引用的目标文件。
因此,尽管在某些平台上可以在使用
-r
选项时为链接器(加载器)指定库,但在其他平台上却不能。解决方法
最初的问题是确定库是否存在。为什么不模仿
autoconf
的做法,并创建一个main.c
,根据偏好,它包含对库中定义的符号的引用,但它可以简单地包含:并使用 C 编译器进行编译和链接:
如果它不起作用,则说明缺少其中一个库。如果您已经检查过
-lc
是否存在,那么您可以推断-lm
已丢失。MacOS X
On MacOS X, the man page for
ld
is quite explicit about the-r
option:So, if you are on MacOS X, the trouble is that
-lm
is not a Mach-O object file, and neither is-lc
. However, in theory, if you have object filesmain.o
,obj1.o
andobj2.o
and you do:then it might work. In practice, it doesn't, and amongst the errors you get:
However, running:
worked without any whingeing from the loader.
Linux
On Linux the man page for
ld
is less explicit, but says:Reading between the lines, this also takes object files and converts them to object files; it does not add libraries into the mix. If you think about it, object files are not created containing references to libraries.
So, although there might be platforms where it is possible to specify libraries to the linker (loader) when using the
-r
option, there are others where it is not.Workarounds
The original problem is to establish whether the libraries are present. Why not mimic what
autoconf
does, and create amain.c
that would, for preference, contain a reference to a symbol defined in the library, but which could simply contain:and compile and link it with the C compiler:
If it doesn't work, then one of the libraries is missing. If you've already checked that
-lc
is present, then you can infer that-lm
is missing.echo $LD_PRELOAD
向您展示了什么?也许错误消息是说
ld
无法找到链接库的.so
。您可以通过将LD_PRELOAD
设置为指向这些.so
文件来提供帮助。What is
echo $LD_PRELOAD
showing you?Perhaps the error message is saying
ld
is unable to find the.so
of the linked libraries. You could help by settingLD_PRELOAD
to point to those.so
files.