根据ld的手册页(以及用于按扩展名链接的gcc),如果命令行中出现-L选项,它将应用于-l指定的所有库,并优先于默认搜索位置。但是,这在我的链接步骤中无效。我在命令行上有这个:
-L / users / me / mylib -lpcre -lz
和/ users / me / mylib包含(副本)libpcre.so和libz.so
这些库存在于系统的其他位置(虽然不一定是相同的版本),我所看到的(Linux上的ldd和Mac上的otool)是引用这些位置中的库的路径。其中一些位置在LD_LIBRARY_PATH上(我在运行的构建环境中无法控制)并且看起来某些位置正在被选中而不是我使用-L的显式设置。
为了清楚起见,这是一个链接步骤问题,而不是运行时问题。网上有很多关于如何在执行时影响/覆盖库位置的信息,我对这一切都很熟悉。在某种意义上,我试图用-L做的是创建一个完全指定的设置。我知道我可以在MacOS上使用install_name_tool解决问题,但我真的很想知道为什么-L不能做它声称的事情。
我使用gcc -Wl学习了一件事,-v是gcc似乎将所有LD_LIBRARY_PATH目录转发到ld。然而,它将它们放在我明确列出的那些之后,而且人们说它们会被搜索,以便它们出现在线上。
答案 0 :(得分:3)
为了清楚起见,这是一个链接步骤问题,而不是运行时问题。
从你所描述的问题来看,我认为你对此并不正确 - 这听起来像是一个运行时问题,你(正当地)正在寻找一种解决方案,你可以在链接时使用它来解决问题你在运行时。
我说它的原因似乎并不是链接的问题,因为它听起来像你的链接正在按预期工作。 LD(或GCC)并没有抱怨链接,你的链接可执行文件正在生产中。您遇到的问题是,当您随后运行这些可执行文件时,加载程序正在查找除您想要的库之外的库。链接期间-L
标志的目的是让链接器知道在哪里可以找到用于准备链接二进制文件的合适库。这与加载器在运行时搜索所需库的位置完全分开。
正如您所说,您已经意识到有一些方法可以在运行时使用(例如更改LD_LIBRARY_PATH
)以避免此问题,方法是更改加载程序搜索库的路径集,但是我宁愿不必这样做,因为无论出于何种原因,你都不一定能控制运行时环境,这是公平的。
幸运的是,我相信有一种设施可以满足您的需求。请查看名为ld
的{{1}}选项(有关完整文档,请参阅GNU ld man page)。基本上,如果您在使用-rpath
选项进行链接期间添加路径,那么这些路径将作为首选位置存储在链接的可执行文件中,以便在运行时查找库,这与查找{{1 }}。这应该适用于Linux或Mac OS X(至少从10.5开始)。
通过gcc将-rpath
选项传递给LD_LIBRARY_PATH
,需要使用-rpath
选项传递该标记。要获取包含ld
的{{1}}命令行,需要-Wl
调用,例如:ld
简而言之,请尝试替换您当前拥有的内容:ld -rpath /custom/path/to/libs
使用:gcc
生成的可执行文件(或库)将存储gcc -Wl,-rpath,/custom/path/to/libs
作为查找库的位置,应查找-L/users/me/mylib -lpcre -lz
和-L/users/me/mylib -Wl,-rpath,/users/me/mylib -lpcre -lz
无需控制/users/me/mylib
。