为什么gcc/ld忽略-L设置?

  • 本文关键字:忽略 设置 ld gcc gcc ld
  • 更新时间 :
  • 英文 :


根据ld(以及用于扩展链接的gcc)的手册页,如果命令行上出现-L选项,它将应用于-L指定的所有库,并且优先于默认的搜索位置。但是,这在我的链接步骤中不起作用。我在命令行中添加了如下内容:

-L/users/me/mylib -lpcre -lz

和/users/me/mylib包含libpcre的副本。So and libz.so

这些库存在于系统的其他位置(尽管不一定是相同的版本),我看到的(Linux上的ldd和Mac上的otool)是引用这些位置中的库的路径。其中一些位置位于LD_LIBRARY_PATH(我无法在我运行的构建环境中控制它)上,并且似乎以某种方式这些位置优先于我使用-L的显式设置。

要清楚,这是一个链接步骤问题,而不是运行时问题。有很多信息在网络上如何影响/覆盖库位置时执行,我熟悉这一切。在某种意义上,我试图用-L来创建一个完全指定的设置。我知道我可以用MacOS上的install_name_tool来解决问题,但是我真的很想理解为什么-L不能做它声称的事情。

我从gcc -Wl,-v中学到的一件事是,gcc似乎将所有的LD_LIBRARY_PATH目录转发给ld.然而,它将它们放在我明确列出的目录之后,并且ld说它们是按照它们出现在行的顺序搜索的。

说明一下,这是一个链接步骤问题,而不是运行时问题。

从你所描述的问题来看,我不认为你是对的——这听起来像是一个运行时问题,你(合理地)在寻找一个解决方案,你可以在链接时使用,这将解决你在运行时遇到的问题。

我说它似乎不是一个问题与链接的原因是,它听起来像你的链接工作,因为它是预期的。LD(或GCC)不会抱怨链接,并且链接的可执行文件正在正常生成。您遇到的问题是,当您随后去运行这些可执行文件时,加载器会找到与您想要的库不同的库。在链接过程中,-L标志的目的是让链接器知道在哪里可以找到合适的库来准备链接的二进制文件。这与加载器在运行时搜索所需库的位置完全分开。

正如您所说,您已经意识到可以在运行时采用一些方法(例如更改LD_LIBRARY_PATH),通过更改加载器搜索库的路径集来避免这个问题,但是您不想这样做,因为无论出于何种原因,您都不一定能够控制运行时环境,这是足够公平的。

幸运的是,有一个设施,我相信会得到你想要的。看看名为-rpathld选项(请参阅GNU ld手册页以获取完整文档)。基本上,如果您使用-rpath选项在链接期间添加路径,这些路径将被存储在链接的可执行文件中,作为在运行时查找库的首选位置,与LD_LIBRARY_PATH中包含的库的搜索方式大致相同。这应该可以在Linux或Mac OS X上工作(至少从10.5开始)。

通过gcc将-rpath选项传递给ld需要使用-Wl选项来传递标志。要获得包含ld -rpath /custom/path/to/libsld命令行,需要调用gcc,如gcc -Wl,-rpath,/custom/path/to/libs

简而言之,尝试替换您当前拥有的内容:-L/users/me/mylib -lpcre -lz

With: -L/users/me/mylib -Wl,-rpath,/users/me/mylib -lpcre -lz

生成的可执行文件(或库)将存储/users/me/mylib作为查找库的地方,并且它应该在那里找到libpcre.solibz.so,而不需要控制LD_LIBRARY_PATH

最新更新