I'm having problems with LD_LIBRARY_PATH
at link time (this question has nothing to do with run time).
我在链接时遇到了LD_LIBRARY_PATH问题(这个问题与运行时无关)。
The link line looks like this when I run make (this is a Linux system using g++ version 4.1.x):
运行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
The -l
options reference shared libraries (e.g., libabc.so) which exist in the directories specified by the -L
options. Those directories also appear in LD_LIBRARY_PATH
. With that configuration, the link is successful, and I can run the application.
-l选项引用在-l选项指定的目录中存在的共享库(例如,libabc.so)。这些目录也出现在LD_LIBRARY_PATH中。有了这个配置,链接成功了,我可以运行应用程序。
If I remove the directories from LD_LIBRARY_PATH
, then I get a single error line such as:
如果我从LD_LIBRARY_PATH中删除目录,则会得到一个错误行,如:
/usr/bin/ld: cannot find -labc
On the other hand, if I remove the directories from the list of -L
options, then I get many warnings such as:
另一方面,如果我从-L选项列表中删除目录,则会得到许多警告,如:
/usr/bin/ld: warning: libabc.so, needed by /long/path/to/libs/libxyz.so,
not found (try using -rpath or -rpath-link)
and then many more errors, such as:
还有更多的错误,比如:
/long/path/to/libs/libdef.so: undefined reference to `Foo::Bar<Baz>::junk(Fred*)'
Can someone explain the difference between LD_LIBRARY_PATH
and -L
? I would like to understand this stuff in depth, so references are greatly appreciated!
有人能解释一下LD_LIBRARY_PATH和-L之间的区别吗?我很想深入了解这个问题,所以非常感谢你的推荐!
Also, what do I have to add to the link line to avoid using LD_LIBRARY_PATH
?
另外,为了避免使用LD_LIBRARY_PATH,需要向链接行添加什么?
EDIT: When directories were missing from -L
, the compiler suggested to "try using -rpath or -rpath-link". I don't think I've ever seen those options in a makefile before. Have you? Not sure if that would help the LD_LIBRARY_PATH
problem though.
编辑:当-L中缺少目录时,编译器建议“尝试使用-rpath或- rpathlink”。我不认为我以前在makefile中见过这些选项。有你吗?但不确定这是否有助于解决LD_LIBRARY_PATH问题。
5 个解决方案
#1
17
The settings of LD_LIBRARY_PATH
has the highest precedence, so when it is set, the set of directories mentioned by LD_LIBRARY_PATH
are searched first even before the standard set
of directories. So in your case setting of LD_LIBRARY_PATH
is influencing the lookup of
the libraries mentioned with -l
option. Without LD_LIBRARY_PATH
some of the dependencies
might have been resolved from the standard set of directories.
LD_LIBRARY_PATH的设置优先级最高,因此在设置时,甚至在标准目录集之前,首先搜索LD_LIBRARY_PATH提到的目录集。因此,在您的案例中,LD_LIBRARY_PATH的设置正在影响使用-l选项提到的库的查找。如果没有LD_LIBRARY_PATH,一些依赖项可能已经从标准目录集解析。
Though setting of LD_LIBRARY_PATH
help with debugging and to try out a newer version of
a library its usage in the general development environment setup and deployment is considered bad.
虽然LD_LIBRARY_PATH的设置有助于调试,并尝试使用一个新版本的库,但它在总体开发环境设置和部署中的使用被认为是糟糕的。
Also refer this HOWTO from Linux Documentation for more details on Shared Libraries
关于共享库的更多细节,请参考Linux文档中的这个how
#2
30
There are two answers to this question, part of the answer lies in the compile-time linking (i.e gcc -lfoo -L/usr/lib
... which in turn calls ld
), and run-time linker lookups.
这个问题有两个答案,部分答案在于编译时链接(i)。e gcc -lfoo -L/usr/lib…然后调用ld)和运行时链接器查找。
When you compile your program, the compiler checks syntax, and then the linker ensures that the symbols required for execution exist (i.e variables / methods / etc), among other things. LD_LIBRARY_PATH
, as has been noted, has the side-effect of altering the way gcc
/ld
behave as well as the way the the run-time linker behaves by modifying the search path.
编译程序时,编译器检查语法,然后链接器确保执行所需的符号存在(i)。除其他外,还有e变量/方法等。如前所述,LD_LIBRARY_PATH的副作用是修改gcc/ld的行为方式以及运行时链接器通过修改搜索路径的行为方式。
When you run your program, the run-time linker actually fetches the shared libraries (on disk or from memory if possible), and loads in the shared symbols / code / etc. Again, LD_LIBRARY_PATH
affects this search path implicitly (sometimes not a good thing, as has been mentioned.)
当您运行您的程序时,运行时链接器实际上会从磁盘或内存中获取共享库,并装入共享符号/代码/等等。
The correct fix for this without using LD_LIBRARY_PATH
on most Linux systems is to add the path that contains your shared libraries to /etc/ld.so.conf
(or in some distributions, create a file in /etc/ld.so.conf.d/
with the path in it) and run ldconfig
(/sbin/ldconfig
as root) to update the runtime linker bindings cache.
在大多数Linux系统上,不使用LD_LIBRARY_PATH的正确方法是添加包含您的共享库到/etc/ld.so的路径。conf(或在某些发行版中,在/etc/ lsd .so.conf中创建一个文件)。d/其中包含路径)并运行ldconfig (/sbin/ldconfig作为根)以更新运行时链接器绑定缓存。
Example on Debian:
在Debian的例子:
jewart@dorfl:~$ cat /etc/ld.so.conf.d/usrlocal.conf
/usr/local/lib
Then when the program is executed, the run-time linker will look in those directories for libraries that your binary has been linked against.
然后,当程序执行时,运行时链接器将在这些目录中查找您的二进制文件所链接的库。
If you want to know what libraries the run-time linker knows about, you can use:
如果您想知道运行时链接器知道哪些库,您可以使用:
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
And, if you want to know what libraries a binary is linked against, you can use ldd
like such, which will tell you which library your runtime linker is going to choose:
而且,如果你想知道二进制文件链接的库是什么,你可以使用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)
#3
8
LD_LIBRARY_PATH
is intended for finding shared libraries when running an application. It is a side effect that it's impacting your link, and you should not rely on that.
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)阶段中搜索,然后在用-L指定的目录中进行搜索(如果没有-L标志的话)。
为什么LD_LIBRARY_PATH是不好的
#4
2
If I were to guess, I would say that the linker is falling back to using LD_LIBRARY_PATH
to resolve libraries that your direct links (e.g., libabc.so
, libdef.so
, and libghi.so
) are dynamically linked against. Looking at the manual page for ld
, it looks like linking against an .so
that was built using -rpath
would affect how the lookup of dynamically bound symbols works.
如果我猜的话,我会说链接器回到使用LD_LIBRARY_PATH来解析直接链接的库(例如libabc)。所以,libdef。所以,和libghi.so)是动态链接的对象。看一下ld的手动页面,它看起来像是链接到。so,使用-rpath构建的,会影响动态绑定符号的查找。
#5
1
Checking the man for g++, I found out that -lxxxxx
option is looking for libxxxxx.a
in the provided path -L
so at linking time , only .a
file will be loaded. At run time, if a library is missing then only library as shared object so .so will be loaded and then it will look in LD_LIBRARY_PATH
. On the executable I am working on , I see that in some library directory, there is the version libxxxx.a
and libxxxx.so
so I think it means that the library can be linked at the linking time or linked at the run time as a shared object.
检查人员的g++,我发现-lxxxxx选项正在查找libxxxxx。在所提供的路径-L中,因此在链接时,只加载一个文件。在运行时,如果一个库丢失了,那么只有库作为共享对象,那么将加载它,然后它将在LD_LIBRARY_PATH中查找。在我正在处理的可执行文件中,我看到在某个库目录中有libxxxx版本。一个和libxxxx。所以我认为这意味着库可以在链接时被链接,也可以在运行时作为共享对象被链接。
If a library exists only as shared object , then it means that the library directory path needs to be LD_LIBRARY_PATH
to be found at the run time. If a library exists only as an archived so .a , then it means that it needs to be linked at the build of the executable and then -L directorypath and -lxxxxx
need to be provided at g++ at compilation time .
如果一个库仅作为共享对象存在,那么它意味着在运行时需要将库目录路径设置为LD_LIBRARY_PATH。如果一个库仅作为一个存档的so .a存在,那么它意味着需要在可执行文件的构建中链接它,然后在编译时需要在g++中提供-L directorypath和-lxxxxx。
This is my understanding .... and at least it is in line with your observations
这是我的理解....至少它与你的观察一致。
#1
17
The settings of LD_LIBRARY_PATH
has the highest precedence, so when it is set, the set of directories mentioned by LD_LIBRARY_PATH
are searched first even before the standard set
of directories. So in your case setting of LD_LIBRARY_PATH
is influencing the lookup of
the libraries mentioned with -l
option. Without LD_LIBRARY_PATH
some of the dependencies
might have been resolved from the standard set of directories.
LD_LIBRARY_PATH的设置优先级最高,因此在设置时,甚至在标准目录集之前,首先搜索LD_LIBRARY_PATH提到的目录集。因此,在您的案例中,LD_LIBRARY_PATH的设置正在影响使用-l选项提到的库的查找。如果没有LD_LIBRARY_PATH,一些依赖项可能已经从标准目录集解析。
Though setting of LD_LIBRARY_PATH
help with debugging and to try out a newer version of
a library its usage in the general development environment setup and deployment is considered bad.
虽然LD_LIBRARY_PATH的设置有助于调试,并尝试使用一个新版本的库,但它在总体开发环境设置和部署中的使用被认为是糟糕的。
Also refer this HOWTO from Linux Documentation for more details on Shared Libraries
关于共享库的更多细节,请参考Linux文档中的这个how
#2
30
There are two answers to this question, part of the answer lies in the compile-time linking (i.e gcc -lfoo -L/usr/lib
... which in turn calls ld
), and run-time linker lookups.
这个问题有两个答案,部分答案在于编译时链接(i)。e gcc -lfoo -L/usr/lib…然后调用ld)和运行时链接器查找。
When you compile your program, the compiler checks syntax, and then the linker ensures that the symbols required for execution exist (i.e variables / methods / etc), among other things. LD_LIBRARY_PATH
, as has been noted, has the side-effect of altering the way gcc
/ld
behave as well as the way the the run-time linker behaves by modifying the search path.
编译程序时,编译器检查语法,然后链接器确保执行所需的符号存在(i)。除其他外,还有e变量/方法等。如前所述,LD_LIBRARY_PATH的副作用是修改gcc/ld的行为方式以及运行时链接器通过修改搜索路径的行为方式。
When you run your program, the run-time linker actually fetches the shared libraries (on disk or from memory if possible), and loads in the shared symbols / code / etc. Again, LD_LIBRARY_PATH
affects this search path implicitly (sometimes not a good thing, as has been mentioned.)
当您运行您的程序时,运行时链接器实际上会从磁盘或内存中获取共享库,并装入共享符号/代码/等等。
The correct fix for this without using LD_LIBRARY_PATH
on most Linux systems is to add the path that contains your shared libraries to /etc/ld.so.conf
(or in some distributions, create a file in /etc/ld.so.conf.d/
with the path in it) and run ldconfig
(/sbin/ldconfig
as root) to update the runtime linker bindings cache.
在大多数Linux系统上,不使用LD_LIBRARY_PATH的正确方法是添加包含您的共享库到/etc/ld.so的路径。conf(或在某些发行版中,在/etc/ lsd .so.conf中创建一个文件)。d/其中包含路径)并运行ldconfig (/sbin/ldconfig作为根)以更新运行时链接器绑定缓存。
Example on Debian:
在Debian的例子:
jewart@dorfl:~$ cat /etc/ld.so.conf.d/usrlocal.conf
/usr/local/lib
Then when the program is executed, the run-time linker will look in those directories for libraries that your binary has been linked against.
然后,当程序执行时,运行时链接器将在这些目录中查找您的二进制文件所链接的库。
If you want to know what libraries the run-time linker knows about, you can use:
如果您想知道运行时链接器知道哪些库,您可以使用:
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
And, if you want to know what libraries a binary is linked against, you can use ldd
like such, which will tell you which library your runtime linker is going to choose:
而且,如果你想知道二进制文件链接的库是什么,你可以使用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)
#3
8
LD_LIBRARY_PATH
is intended for finding shared libraries when running an application. It is a side effect that it's impacting your link, and you should not rely on that.
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)阶段中搜索,然后在用-L指定的目录中进行搜索(如果没有-L标志的话)。
为什么LD_LIBRARY_PATH是不好的
#4
2
If I were to guess, I would say that the linker is falling back to using LD_LIBRARY_PATH
to resolve libraries that your direct links (e.g., libabc.so
, libdef.so
, and libghi.so
) are dynamically linked against. Looking at the manual page for ld
, it looks like linking against an .so
that was built using -rpath
would affect how the lookup of dynamically bound symbols works.
如果我猜的话,我会说链接器回到使用LD_LIBRARY_PATH来解析直接链接的库(例如libabc)。所以,libdef。所以,和libghi.so)是动态链接的对象。看一下ld的手动页面,它看起来像是链接到。so,使用-rpath构建的,会影响动态绑定符号的查找。
#5
1
Checking the man for g++, I found out that -lxxxxx
option is looking for libxxxxx.a
in the provided path -L
so at linking time , only .a
file will be loaded. At run time, if a library is missing then only library as shared object so .so will be loaded and then it will look in LD_LIBRARY_PATH
. On the executable I am working on , I see that in some library directory, there is the version libxxxx.a
and libxxxx.so
so I think it means that the library can be linked at the linking time or linked at the run time as a shared object.
检查人员的g++,我发现-lxxxxx选项正在查找libxxxxx。在所提供的路径-L中,因此在链接时,只加载一个文件。在运行时,如果一个库丢失了,那么只有库作为共享对象,那么将加载它,然后它将在LD_LIBRARY_PATH中查找。在我正在处理的可执行文件中,我看到在某个库目录中有libxxxx版本。一个和libxxxx。所以我认为这意味着库可以在链接时被链接,也可以在运行时作为共享对象被链接。
If a library exists only as shared object , then it means that the library directory path needs to be LD_LIBRARY_PATH
to be found at the run time. If a library exists only as an archived so .a , then it means that it needs to be linked at the build of the executable and then -L directorypath and -lxxxxx
need to be provided at g++ at compilation time .
如果一个库仅作为共享对象存在,那么它意味着在运行时需要将库目录路径设置为LD_LIBRARY_PATH。如果一个库仅作为一个存档的so .a存在,那么它意味着需要在可执行文件的构建中链接它,然后在编译时需要在g++中提供-L directorypath和-lxxxxx。
This is my understanding .... and at least it is in line with your observations
这是我的理解....至少它与你的观察一致。