使用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
它有效,但当我与
链接时ld -r -o main1.o main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm
抱怨
ld: cannot find -lc
ld: cannot find -lm
我实际上并没有尝试以这种方式编译代码,而是我试图弄清楚为什么别人的测试看看是否存在库是不行的。 (因此我真的不明白ld
发生了什么......通常我只是用GCC来链接)
为什么告诉ld
以可重定位的方式链接会让它突然无法找到库?如果我只想测试-lm
是否存在,除了
ld -r -lm
以便找到图书馆?
如果你想查看我正在处理的源代码,可以在这里下载:https://github.com/jeremysalwen/ESPS(注意,第一次提交是原始源代码,后续提交是我个人所做的更改制成。)
答案 0 :(得分:3)
在MacOS X上,ld
的手册页非常清楚-r
选项:
-r
合并目标文件以生成另一个文件类型为MH_OBJECT的mach-o目标文件。
因此,如果您使用的是MacOS X,则问题是-lm
不是Mach-O目标文件,-lc
也不是。{1}}。但是,从理论上讲,如果您有目标文件main.o
,obj1.o
和obj2.o
,那么您可以:
cp obj1.o ./-lm
cp obj2.o ./-lc
ld -r -o main1.o main.o -lm -lc
那么它可能会奏效。在实践中,它没有,并且在你得到的错误中:
ld: warning: unexpected dylib (/usr/lib/libm.dylib) on link line
ld: warning: unexpected dylib (/usr/lib/libc.dylib) on link line
然而,运行:
ld -r -o main1.o -arch x86_64 main.o obj1.o obj2.o
没有任何来自装载机的抱怨。
在Linux上,ld
的手册页不那么明确,但是说:
-i
执行增量链接(与选项-r相同)。
-r
--relocatable
生成可重定位输出---即生成一个输出文件,该文件又可以作为
ld
的输入。这通常称为部分链接。作为副作用,在支持标准Unix幻数的环境中,此选项还将输出文件的幻数设置为“OMAGIC”。如果未指定此选项,则会生成绝对文件。链接C ++程序时,此选项不会解析对构造函数的引用;要做到这一点,请使用-Ur
。如果输入文件的格式与输出文件的格式不同,则仅当输入文件不包含任何重定位时,才支持部分链接。不同的输出格式会有进一步的限制;例如,一些基于“a.out”的格式不支持与其他格式的输入文件进行部分链接。
此选项与
-i
完全相同。
在行之间读取,这也会获取目标文件并将它们转换为目标文件;它不会将库添加到组合中。如果你考虑一下,就不会创建包含对库的引用的目标文件。
因此,尽管在使用-r
选项时可能存在可以为链接器(加载器)指定库的平台,但还有一些不是。{/ p>
最初的问题是确定库是否存在。为什么不模仿autoconf
做什么,并创建一个main.c
,优先包含对库中定义的符号的引用,但它可以只包含:
int main(void){return 0;}
并使用C编译器编译并链接它:
cc -o main main.c -lm -lc
如果它不起作用,则缺少其中一个库。如果您已检查-lc
是否存在,那么您可以推断-lm
缺失。
答案 1 :(得分:0)
echo $LD_PRELOAD
显示什么?
可能错误消息是ld
无法找到链接库的.so
。您可以通过将LD_PRELOAD
设置为指向那些.so
文件来提供帮助。