如何指定库路径的首选项?

Hei*_*ing 83 c++ linker g++

我正在用g++和编译一个c ++程序ld.我有一个.so我希望在链接期间使用的库.但是,存在一个同名的库/usr/local/lib,并且ld正在选择我直接指定的库.我怎样才能解决这个问题?

对于下面的示例,我的库文件是/my/dir/libfoo.so.0.我尝试过的东西不起作用:

  • 我的g ++命令是 g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
  • 添加/my/dir到我的$PATHen`变量的开头或结尾
  • 添加/my/dir/libfoo.so.0为g ++的参数

ste*_*anB 85

添加新库所在的路径LD_LIBRARY_PATH(在Mac上它的名称略有不同......)

您的解决方案应该使用-L/my/dir -lfoo选项,在运行时使用LD_LIBRARY_PATH指向库的位置.

小心使用LD_LIBRARY_PATH - 简而言之(来自链接):

..implications ..:
安全性:请记住LD_LIBRARY_PATH中指定的目录在(!)标准位置之前被搜索?这样,一个讨厌的人可能会让你的应用程序加载一个包含恶意代码的共享库版本!这就是为什么setuid/setgid可执行文件忽略了这个变量的原因之一!
性能:链接加载器必须搜索指定的所有目录,直到找到共享库所在的目录 - 对于应用程序链接的所有共享库!这意味着很多系统调用open(),这将失败"ENOENT(没有这样的文件或目录)"!如果路径包含许多目录,则失败调用的数量将线性增加,您可以从应用程序的启动时间告知.如果某些(或所有)目录位于NFS环境中,那么应用程序的启动时间实际上可能会变长 - 并且可能会降低整个系统的速度!
不一致:这是最常见的问题.LD_LIBRARY_PATH强制应用程序加载未链接的共享库,这很可能与原始版本不兼容.这可能是非常明显的,即应用程序崩溃,或者它可能导致错误的结果,如果拾取的库不能完全执行原始版本.特别是后者有时难以调试.

要么

通过gcc使用rpath选项到链接器 - 运行时库搜索路径,将使用而不是查找标准目录(gcc选项):

-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)
Run Code Online (Sandbox Code Playgroud)

这对临时解决方案很有用.在查看标准目录之前,链接器首先在LD_LIBRARY_PATH中搜索库.

如果您不想永久更新LD_LIBRARY_PATH,可以在命令行上执行以下操作:

LD_LIBRARY_PATH=/some/custom/dir ./fooo
Run Code Online (Sandbox Code Playgroud)

您可以检查链接器使用哪些库知道(示例):

/sbin/ldconfig -p | grep libpthread
        libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0
Run Code Online (Sandbox Code Playgroud)

您可以检查您的应用程序使用的库:

ldd foo
        linux-gate.so.1 =>  (0xffffe000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000)
        librt.so.1 => /lib/librt.so.1 (0xb7e65000)
        libm.so.6 => /lib/libm.so.6 (0xb7d5b000)
        libc.so.6 => /lib/libc.so.6 (0xb7c2e000)
        /lib/ld-linux.so.2 (0xb7fc7000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000)
        libz.so.1 => /lib/libz.so.1 (0xb7c18000)
Run Code Online (Sandbox Code Playgroud)

  • 在运行时搜索`LD_LIBRARY_PATH`,在编译时要设置`LIBRARY_PATH`.请参阅https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html (18认同)

Mic*_*eer 21

这是一个老问题,但似乎没有人提到这一点.

你很幸运,事情就是联系在一起.

你需要改变

g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
Run Code Online (Sandbox Code Playgroud)

对此:

g++ -g -Wall -o my_binary -L/my/dir bar.cpp -lfoo
Run Code Online (Sandbox Code Playgroud)

您的链接器会跟踪它需要解析的符号.如果它首先读取库,则它没有任何所需的符号,因此忽略其中的符号.在需要链接到它们之后指定库,以便链接器中包含要在其中查找的符号.

此外,-lfoo使其专门搜索名为libfoo.alibfoo.so根据需要的文件.没有libfoo.so.0.因此,无论ln是名称还是将库重命名为appopriate.

引用gcc手册页:

-l library
   ...
   It makes a difference where in the command you 
   write this option; the linker searches and processes 
   libraries and object files in the order they are 
   specified.  Thus, foo.o -lz bar.o searches library z 
   after file foo.o but before bar.o.  If bar.o refers 
   to functions in z, those functions may not be loaded.
Run Code Online (Sandbox Code Playgroud)

直接将文件添加到g++命令行应该有效,除非你先把它放在前面bar.cpp,导致链接器因缺少任何需要的符号而忽略它,因为还不需要符号.


R S*_*hko 20

指定库的绝对路径应该可以正常工作:

g++ /my/dir/libfoo.so.0  ...
Run Code Online (Sandbox Code Playgroud)

你记得在-lfoo添加绝对路径后删除了吗?


Ale*_*mez 11

作为替代方案,您可以使用环境变量LIBRARY_PATHCPLUS_INCLUDE_PATH,分别指示在何处寻找库和在哪里找头(CPATH也将做的工作),不指定-L和-I选项.

编辑: CPATH包括与报头-ICPLUS_INCLUDE_PATH-isystem.