Linux中-l 与-ld的区别,关于linux:在链接时LD_LIBRARY_PATH和-L有什么区别?

我在链接时遇到LD_LIBRARY_PATH的问题(此问题与运行时无关)。

运行make时,链接线如下所示(这是使用g ++版本4.1.x的Linux系统):

g++ a.o b.o c.o -o myapp \

-L/long/path/to/libs/ \

-L/another/long/path/ \

-labc -ldef -lghi

-l选项引用共享库(例如libabc.so),这些共享库位于-l选项指定的目录中。这些目录也出现在LD_LIBRARY_PATH中。使用该配置,链接成功,并且我可以运行该应用程序。

如果我从LD_LIBRARY_PATH中删除目录,则会得到一条错误行,例如:

/usr/bin/ld: cannot find -labc

另一方面,如果我从-l选项列表中删除目录,则会收到许多警告,例如:

/usr/bin/ld: warning: libabc.so, needed by /long/path/to/libs/libxyz.so,

not found (try using -rpath or -rpath-link)

然后出现更多错误,例如:

/long/path/to/libs/libdef.so: undefined reference to `Foo::Bar::junk(Fred*)'

有人可以解释LD_LIBRARY_PATH和-l之间的区别吗?我想深入了解这些内容,因此非常感谢参考!

另外,为了避免使用LD_LIBRARY_PATH,我必须添加什么到链接行?

编辑:-l中缺少目录时,编译器建议"尝试使用-rpath或-rpath-link"。我认为我以前从未在Makefile中看到过这些选项。你有吗不知道这是否可以解决LD_LIBRARY_PATH问题。

该问题有两个答案,部分答案在于编译时链接(即gcc -lfoo -L/usr/lib ...依次调用ld)和运行时链接程序查找。

编译程序时,编译器将检查语法,然后链接器确保执行所需的符号(即变量/方法/等)存在。如前所述,LD_LIBRARY_PATH具有通过修改搜索路径来更改gcc / ld行为方式以及运行时链接程序行为方式的副作用。

当您运行程序时,运行时链接程序实际上会(从磁盘或从内存中)获取共享库,并加载共享符号/代码/等。同样,LD_LIBRARY_PATH会隐式影响此搜索路径(有时不会)如前所述是一件好事。)

在大多数Linux系统上不使用LD_LIBRARY_PATH的情况下,正确的解决方法是将包含共享库的路径添加到/etc/ld.so.conf(或在某些发行版中,在/etc/ld.so.conf.d/中创建一个包含路径的文件)并运行< x17>(以/sbin/ldconfig为根)更新运行时链接程序绑定缓存。

关于Debian的示例:

jewart@dorfl:~$ cat /etc/ld.so.conf.d/usrlocal.conf

/usr/local/lib

然后,在执行程序时,运行时链接程序将在那些目录中查找二进制文件已链接到的库。

如果您想知道运行时链接程序知道哪些库,可以使用:

jewart@dorfl:~$ ldconfig -v

/usr/lib:

libbfd-2.18.0.20080103.so -> libbfd-2.18.0.20080103.so

libkdb5.so.4 -> libkdb5.so.4.0

libXext.so.6 -> libXext.so.6.4.0

而且,如果您想知道二进制文件针对的是哪些库,则可以像这样使用ldd,它会告诉您运行时链接程序将选择哪个库:

jewart@dorfl:~$ ldd /bin/ls

linux-vdso.so.1 =>  (0x00007fffda1ff000)

librt.so.1 => /lib/librt.so.1 (0x00007f5d2149b000)

libselinux.so.1 => /lib/libselinux.so.1 (0x00007f5d2127f000)

libacl.so.1 => /lib/libacl.so.1 (0x00007f5d21077000)

libc.so.6 => /lib/libc.so.6 (0x00007f5d20d23000)

+1,简洁明了地描述了链接和加载的工作方式。 ld.so.conf似乎与LD_LIBRARY_PATH可能会有一些相同的问题,尽管它不会影响链接时间,而只会影响运行时-在此以xahlee.org/提及。 UnixResource%5Fdir /%5F /尝试改进。

但是,我仍然不明白为什么缺少LD_LIBRARY_PATH会阻止链接。不能编辑ld.so.conf。如果是这样,它甚至可以解决从LD_LIBRARY_PATH中删除目录时在链接时遇到的问题吗?

我阅读原始帖子的方式如下:使用-L / path / to / lib1 -L / path / to / lib2and3 -llib1 -llib2 -llib3可以工作,但是除非LD_LIBRARY_PATH具有/ path / to / lib { 1,2and3}。如果编译时链接失败,则-L路径有问题...您可以发布实际的失败编译命令吗?

否...除非LD_LIBRARY_PATH包含/ path / to / lib {1,2,3},否则它的链接将失败。我将检查LD_LIBRARY_PATH与-L指定的内容之间是否存在差异。不幸的是,我无法发布编译命令。无论LD_LIBRARY_PATH设置为什么,它都不会影响make作为compiling / link命令吐出的内容。

正确,您不会在输出中看到它,无论是由人工编写还是由自动工具计算出的Makefile。您看到的错误实际上可能早于您编译特定二进制文件的时间吗?也许是由于试图编译的依赖项(ala autoconfs测试是否存在库)而失败,因为您的libabc.so不在标准位置(并且未通过-L显式指定)?那是在使用LD_LIBRARY_PATH set进行编译/自动配置的情况下...

当您说" LD_LIBRARY_PATH,正如已经提到的那样,具有通过修改搜索路径来改变gcc / ld行为方式以及运行时链接程序行为方式的副作用"。

LD_LIBRARY_PATH的设置具有最高的优先级,因此,设置它时,甚至在标准设置之前就先搜索LD_LIBRARY_PATH提及的目录集。

目录。因此,在您的情况下,LD_LIBRARY_PATH的设置会影响对

使用-l选项提到的库。没有LD_LIBRARY_PATH的某些依赖项

可能已经从标准目录集中解决了。

虽然LD_LIBRARY_PATH的设置有助于调试并尝试更新版本的

库在一般开发环境的设置和部署中的使用被认为是不好的。

另请参阅Linux文档中的本HOWTO,以获取有关共享库的更多详细信息。

声明某事是"坏"而不说原因,这绝对是"坏"的事情(我可以??说为什么)。

LD_LIBRARY_PATH用于在运行应用程序时查找共享库。这是一个副作用,它会影响您的链接,因此您不应依赖它。

As an often unwanted side effect,

LD_LIBRARY_PATH will also be searched

at link (ld) stage after directories

specified with -L (also if no -L flag

is given).

为什么LD_LIBRARY_PATH不好

我同意它的副作用,我希望不要依赖它。但是我不确定将目录放在哪里而不是放在LD_LIBRARY_PATH中-因为仅将它们放在-L中显然不够好。感谢您的链接-祝您阅读愉快!

导致LD_LIBRARY_PATH发生故障并使我们想要在/etc/ld.so.conf中添加路径的副作用是什么?

如果我猜到了,我会说链接器退回到使用LD_LIBRARY_PATH来解析动态链接直接链接到您的直接链接(例如,libabc.so,libdef.so和libghi.so)的库。查看ld的手册页,似乎链接到使用-rpath构建的.so会影响动态绑定符号的查找方式。

检查该人的g ++,我发现-lxxxxx选项正在提供的路径-l中寻找libxxxxx.a,因此在链接时,只会加载.a文件。在运行时,如果缺少库,则仅将库作为共享库,因此将加载.so,然后它将在LD_LIBRARY_PATH中查找。在我正在处理的可执行文件上,我看到某些库目录中有版本libxxxx.a和libxxxx.so,所以我认为这意味着可以在链接时链接该库,也可以在运行时将该库链接为共享对象。

如果库仅作为共享库存在,则意味着在运行时必须找到库目录路径为LD_LIBRARY_PATH。

如果一个库仅以.a的形式存在,则意味着它需要在可执行文件的构建中链接,然后在编译时在g ++上提供-L directorypath和-lxxxxx。

这是我的理解..至少与您的观察一致

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值