Linux:控制`ld` 在哪里搜索.o 目标文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5488840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:28:21  来源:igfitidea点击:

Linux: controlling where `ld` searches for .o object files?

linuxsearchobjectpathld

提问by sdaau

Ok, this is the situation: I'm trying to use some older software: works fine on Ubuntu Lucid, fails on Natty.

好的,情况就是这样:我正在尝试使用一些较旧的软件:在 Ubuntu Lucid 上运行良好,在 Natty 上失败。

So, I straced around a bit, and it turns out that this software calls ld, and ldeventually fails with:

所以,我strace转了一圈ld,结果发现这个软件调用了,ld最终失败了:

.../ld: crt1.o: No such file: No such file or directory

... yes, the old crti.o file missingerror :) However, I'd like to ask the question in more general terms...

...是的,旧的crti.o 文件丢失错误:) 但是,我想用更一般的术语来问这个问题......

The thing is, this is 'standalone' (older) ldhere, and when I run .../ld -verbose | less, I get:

问题是,这里是“独立”(较旧)ld,当我运行时.../ld -verbose | less,我得到:

...
SEARCH_DIR("/usr/local/lib"); 
SEARCH_DIR("/lib"); 
SEARCH_DIR("/usr/lib");
...

Now, the thing is that:

现在,事情是这样的:

  • On Lucid, crt1.ois in /usr/lib/crt1.o
  • On Natty, crt1.ois in /usr/lib/i386-linux-gnu/crt1.o
  • 在 Lucid,crt1.o/usr/lib/crt1.o
  • 在 Natty 上,crt1.o/usr/lib/i386-linux-gnu/crt1.o

... so no surprise why crt1.ocannot be found, I guess. It seems, all I have to do, is tell ldto look for crt1.oin /usr/lib/i386-linux-gnu, but how do I do that?

......所以crt1.o我猜为什么找不到,也就不足为奇了。看来,我所要做的就是告诉ld寻找crt1.oin /usr/lib/i386-linux-gnu,但我该怎么做?

I thought I could use the -Loption, but man ldsays:

我以为我可以使用该-L选项,但man ld说:

to link a file "hello.o":

    ld -o <output> /lib/crt0.o hello.o -lc

  This tells ld to produce a file called output as the result of linking
  the file "/lib/crt0.o" with "hello.o" and the library "libc.a", which
  will come from the standard search directories. 
...

-L searchdir
--library-path=searchdir
  Add path searchdir to the list of paths that ld will search for
  archive libraries and ld control scripts.

... meaning, '-L' would influence where we look for "libc.a" (in man example) - but not for the object files.

... 意思是, ' -L' 会影响我们寻找 " libc.a" 的位置(在 man 示例中) - 但不会影响目标文件。

I would actually prefer an environment variable for this, but I tried both LD_PRELOAD_PATHand LD_LIBRARY_PATHto no avail (I guess, those are related to "shared objects", and these .ofiles aren't one of those).

我真的喜欢一个环境变量,但我都尝试LD_PRELOAD_PATH,并LD_LIBRARY_PATH没有用(我想,这些都涉及到“共享对象”,而这些.o文件不是其中之一)。

Does anyone know if there is an environment variable (preferably - or if not, command line option to ld) that would control where ldsearches for .oobject files?

有谁知道是否有一个环境变量(最好 - 或者如果没有,命令行选项ld)可以控制在哪里ld搜索.o目标文件?

As a note, I guess I could just symlink /usr/lib/i386-linux-gnu/crt1.oin /usr/lib/, but I'd rather use an environment variable, if it exists... If not, are there any other possible solutions to this?

作为一个说明,我想我可能只是符号链接/usr/lib/i386-linux-gnu/crt1.o/usr/lib/,但我宁愿使用环境变量,如果存在的话...如果没有,是否有这个任何其他可能的解决方案?

Thank in advance for any answers,
Cheers!

提前感谢您的任何答案,
干杯!

EDIT: possibly relevant: Daniel Kegel - --with-sysroot newbie troubles: "ld: cannot open crt1.o"

编辑:可能相关:Daniel Kegel - --with-sysroot 新手问题:“ld:无法打开 crt1.o”

采纳答案by richvdh

lddoesn't use a search path for .ofiles at all - you must pass it the full path (as in the example you quote from the manual). So no, there is no way to change the search path it uses to find .ofiles.

ld根本不使用.o文件的搜索路径- 您必须将完整路径传递给它(如您从手册中引用的示例)。所以不,没有办法改变它用来查找.o文件的搜索路径。

In general, ldshouldn't be called directly - for instance you'd normally call gccinstead to do your linking. I'd say it's the program calling ldwhich is at fault here.

通常,ld不应直接调用 - 例如,您通常会调用gcc来进行链接。我会说这是程序调用ld这里有问题。

回答by user237419

if that's and x86_64 machine (I think it is) then you should make sure you have libc6-dev installed (i think the other crt1.o is libc6-dev-i386's file IF natty is renaming the 32bit libs folders (on previous releases its /usr/lib32) ....

如果那是 x86_64 机器(我认为是),那么您应该确保安装了 libc6-dev(我认为另一个 crt1.o 是 libc6-dev-i386 的文件,如果 natty 正在重命名 32 位 libs 文件夹(在以前的版本中,它的/usr/lib32) ....

if you're compiling for 32bit and you get that error... that must be a bug in gcc/g++; try giving it the path with the -B option

如果你正在编译 32 位并且你得到那个错误......那一定是 gcc/g++ 中的一个错误;尝试使用 -B 选项为其指定路径

回答by sdaau

OK, after some messing about, I think I managed to solve my original problem (though note, as far as the original question goes, it's still the same answer as the accepted answer):

好的,经过一番折腾,我想我设法解决了我原来的问题(但请注意,就原来的问题而言,它仍然是与接受的答案相同的答案):

LIBRARY_PATH=/lib/i386-linux-gnu:/usr/lib/i386-linux-gnu:$LIBRARY_PATH myprogram --args..

Here is the distinction which I should remember:

这是我应该记住的区别:

  • LD_LIBRARY_PATHis used to 'help' an executable find library files, when it is run (i.e. loading, LD_)
  • LIBRARY_PATHhelps gcc, g++and company find libraries referenced via '-l' argument (for instance, -ldl, i.e. libdl, which was also a problem in my case; see man g++for more on LIBRARY_PATH)
  • LD_LIBRARY_PATH用于“帮助”可执行文件在运行时(即加载LD_)查找库文件
  • LIBRARY_PATHhelp gccg++并且公司找到通过 ' -l' 参数引用的库(例如,-ldl, ie libdl,这在我的情况下也是一个问题;man g++有关更多信息,请参见LIBRARY_PATH

So since myprogramwas calling g++, ldand such, and those were crashing unable to find the libraries during compilation - adding the LIBRARY_PATHargument seems to have fixed the g++/ldbehavior, and so I don't get problems (even with crt1.o!) anymore with myprogram.. Hopefully that will last :)

所以,既然myprogram是打电话g++ld和这样的,和那些被撞毁无法找到编译时库-添加LIBRARY_PATH说法似乎已经解决了这一g++/ld行为,所以我不明白的问题(即使有crt1.o!)用了myprogram..希望这会持续 :)

Thanks all for the help,
Cheers!

感谢大家的帮助,
干杯!

回答by Vladyslav Savchenko

You can use also --sysroot:

您也可以使用 --sysroot:

   --sysroot=dir
       Use dir as the logical root directory for headers and libraries.  For example, if the compiler normally searches for headers in /usr/include and libraries in /usr/lib, it instead searches
       dir/usr/include and dir/usr/lib.

       If you use both this option and the -isysroot option, then the --sysroot option applies to libraries, but the -isysroot option applies to header files.

       The GNU linker (beginning with version 2.16) has the necessary support for this option.  If your linker does not support this option, the header file aspect of --sysroot still works, but the
       library aspect does not.

!!! => The GNU linker (beginning with version 2.16) has the necessary support for this option.

!!!=> GNU 链接器(从 2.16 版开始)对此选项有必要的支持。