1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library会找不到
2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到
比如安装了一个mysql到/usr/local/mysql,mysql有一大堆library在/usr/local/mysql/lib下面,这时就需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib,保存过后ldconfig一下,新的library才能在程序运行时被找到。
3. 如果想在这两个目录以外放lib,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。
4. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。
5. 总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。
几个特殊的环境变量:
LD_LIBRARY_PATH 这个环境变量是大家最为熟悉的,它告诉loader:在哪些目录中可以找到共享库。可以设置多个搜索目录,这些目录之间用冒号分隔开。在linux下,还提供了另外一种方式来完成同样的功能,你可以把这些目录加到/etc/ld.so.conf中,或则在/etc/ld.so.conf.d里创建一个文件,把目录加到这个文件里。当然,这是系统范围内全局有效的,而环境变量只对当前shell有效。按照惯例,除非你用上述方式指明,loader是不会在当前目录下去找共享库的,正如shell不会在当前目前找可执行文件一样。
LD_PRELOAD 这个环境变量对于程序员来说,也是特别有用的。它告诉loader:在解析函数地址时,优先使用LD_PRELOAD里指定的共享库中的函数。这为调试提供了方便,比如,对于C/C++程序来说,内存错误最难解决了。常见的做法就是重载malloc系列函数,但那样做要求重新编译程序,比较麻烦。使用 LD_PRELOAD机制,就不用重新编译了,把包装函数库编译成共享库,并在LD_PRELOAD加入该共享库的名称,这些包装函数就会自动被调用了。在linux下,还提供了另外一种方式来完成同样的功能,你可以把要优先加载的共享库的文件名写在/etc/ld.so.preload里。当然,这是系统范围内全局有效的,而环境变量只对当前shell有效。
=======================================
Linux下共享库路径配置问题
问题由来:
安装了程序,执行时报错: error while loading shared libraries: libmsg_queue.so.0: cannot open shared object file:
No such file or directory
可是查找一下,确实有此链接文件,它在/usr/local/lib下,指向文件libmsg_queue.so.0.0.0
导致问题的原因是执行了ldconfig命令(需要root用户)
ldconfig会打开/etc/ld.so.conf文件,把其中列出的目录下的库读到缓冲区.如果有新的库文件安装到库文件目录下而不是
/usr/lib或/lib,你必需再次运行这个命令.它会生成一个叫ld.so.cache的文件(不要去编辑它).
新的问题:
/etc/ld.so.conf文件有什么作用呢?如果/etc/ld.so.conf中包含/usr/local/lib,在每次往/usr/local/lib增加库的时是否都
需要执行ldconfig?并且是不是环境变量LD_LIBRARY_PATH能解决这个问题?
当执行ldconfig时,立即生成库缓冲.如果你在执行ldconfig之后安装了库文件,则系统就不知道它的存在,所以必需再次运行它.
就ldconfig作用来说,当库缓存加入系统时,ldconfig就会指定一个在/etc/ld.so.conf文件中所列目录中的库的列表.在应用程
序加载的时候,它就会询问ld-linux.so.2(动态链接库链接器)来加载共享库.
查看应用程序请求ld-linux.so.2为其加载的库是哪种类型?指令是
ldd <application name>
如果想看ldconfig执行时哪些库被缓冲,执行命令:
ldconfig -v | more
显示/lib,/usr/lib和/etc/ld.so.conf中指定路径中的库并缓存
LD_LIBRARY_PATH不同,被认为优缺点并存,易被误用.使用它经常会覆盖其他的缺省库链接路径.如:
export LD_LIBRARY_PATH=$HOME/gnome-1.4/lib:$LD_LIBRARY_PATH
这样能够保证$HOME/gonme-1.4/lib下的库甚至能够优先于/usr/lib下的相同的库被ld-linux.so.2调用.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/gnome-1.4/lib
这样执行自己的库就不会被优先被加载了.
问题:
是否在自己的环境变量LD_LIBRARY_PATH中包含/usr/local/lib来代替每次在/usr/local/lib中增加库后必需记住去运行
ldconfig呢?这种方法不是更有效吗?
LD_LIBRARY_PATH变量能够覆盖缺省的共享库路径,而不管ldconfig增加新库到系统.如要永久地设置库路径,除非把
LD_LIBRARY_PATH加进如/etc/profile,/etc/bashrc等文件中.否则执行依赖特殊库路径的程序时,每次执行程序时
LD_LIBRARY_PATH都必需重新定义.
所以,事实上选择LD_LIBRARY_PATH或ldconfig没有什么不同,只是取决于你想使用它做什么.技术上讲,"正确"的方法是使
用/etc/ld.so.conf,但是在Linux系统上总是有多种方法取得同样的结果.
2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到
比如安装了一个mysql到/usr/local/mysql,mysql有一大堆library在/usr/local/mysql/lib下面,这时就需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib,保存过后ldconfig一下,新的library才能在程序运行时被找到。
3. 如果想在这两个目录以外放lib,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。
4. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。
5. 总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。
几个特殊的环境变量:
LD_LIBRARY_PATH 这个环境变量是大家最为熟悉的,它告诉loader:在哪些目录中可以找到共享库。可以设置多个搜索目录,这些目录之间用冒号分隔开。在linux下,还提供了另外一种方式来完成同样的功能,你可以把这些目录加到/etc/ld.so.conf中,或则在/etc/ld.so.conf.d里创建一个文件,把目录加到这个文件里。当然,这是系统范围内全局有效的,而环境变量只对当前shell有效。按照惯例,除非你用上述方式指明,loader是不会在当前目录下去找共享库的,正如shell不会在当前目前找可执行文件一样。
LD_PRELOAD 这个环境变量对于程序员来说,也是特别有用的。它告诉loader:在解析函数地址时,优先使用LD_PRELOAD里指定的共享库中的函数。这为调试提供了方便,比如,对于C/C++程序来说,内存错误最难解决了。常见的做法就是重载malloc系列函数,但那样做要求重新编译程序,比较麻烦。使用 LD_PRELOAD机制,就不用重新编译了,把包装函数库编译成共享库,并在LD_PRELOAD加入该共享库的名称,这些包装函数就会自动被调用了。在linux下,还提供了另外一种方式来完成同样的功能,你可以把要优先加载的共享库的文件名写在/etc/ld.so.preload里。当然,这是系统范围内全局有效的,而环境变量只对当前shell有效。
LD_ DEBUG 这个环境变量比较好玩,有时使用它,可以帮助你查找出一些共享库的疑难杂症(比如同名函数引起的问题)。同时,利用它,你也可以学到一些共享库加载过程的知识。它的参数如下:
libs display library search paths
reloc display relocation processing
files display progress for input file
symbols display symbol table processing
bindings display information about symbol binding
versions display version dependencies
all all previous options combined
statistics display relocation statistics
unused determined unused DSOs
help display this help message and exit
BIND_NOW 这个环境变量与dlopen中的flag的意义是一致,只是dlopen中的flag适用于显示加载的情况,而BIND_NOW/BIND_NOT适用于隐式加载。
LD_PROFILE/LD_PROFILE_OUTPUT:为指定的共享库产生profile数据,LD_PROFILE指定共享库的名称,LD_PROFILE_OUTPUT指定输出profile文件的位置,是一个目录,且必须存在,默认的目录为/var/tmp/或/var/profile。通过profile数据,你可以得到一些该共享库中函数的使用统计信息。
=======================================
Linux下共享库路径配置问题
问题由来:
安装了程序,执行时报错: error while loading shared libraries: libmsg_queue.so.0: cannot open shared object file:
No such file or directory
可是查找一下,确实有此链接文件,它在/usr/local/lib下,指向文件libmsg_queue.so.0.0.0
导致问题的原因是执行了ldconfig命令(需要root用户)
ldconfig会打开/etc/ld.so.conf文件,把其中列出的目录下的库读到缓冲区.如果有新的库文件安装到库文件目录下而不是
/usr/lib或/lib,你必需再次运行这个命令.它会生成一个叫ld.so.cache的文件(不要去编辑它).
新的问题:
/etc/ld.so.conf文件有什么作用呢?如果/etc/ld.so.conf中包含/usr/local/lib,在每次往/usr/local/lib增加库的时是否都
需要执行ldconfig?并且是不是环境变量LD_LIBRARY_PATH能解决这个问题?
当执行ldconfig时,立即生成库缓冲.如果你在执行ldconfig之后安装了库文件,则系统就不知道它的存在,所以必需再次运行它.
就ldconfig作用来说,当库缓存加入系统时,ldconfig就会指定一个在/etc/ld.so.conf文件中所列目录中的库的列表.在应用程
序加载的时候,它就会询问ld-linux.so.2(动态链接库链接器)来加载共享库.
查看应用程序请求ld-linux.so.2为其加载的库是哪种类型?指令是
ldd <application name>
如果想看ldconfig执行时哪些库被缓冲,执行命令:
ldconfig -v | more
显示/lib,/usr/lib和/etc/ld.so.conf中指定路径中的库并缓存
LD_LIBRARY_PATH不同,被认为优缺点并存,易被误用.使用它经常会覆盖其他的缺省库链接路径.如:
export LD_LIBRARY_PATH=$HOME/gnome-1.4/lib:$LD_LIBRARY_PATH
这样能够保证$HOME/gonme-1.4/lib下的库甚至能够优先于/usr/lib下的相同的库被ld-linux.so.2调用.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/gnome-1.4/lib
这样执行自己的库就不会被优先被加载了.
问题:
是否在自己的环境变量LD_LIBRARY_PATH中包含/usr/local/lib来代替每次在/usr/local/lib中增加库后必需记住去运行
ldconfig呢?这种方法不是更有效吗?
LD_LIBRARY_PATH变量能够覆盖缺省的共享库路径,而不管ldconfig增加新库到系统.如要永久地设置库路径,除非把
LD_LIBRARY_PATH加进如/etc/profile,/etc/bashrc等文件中.否则执行依赖特殊库路径的程序时,每次执行程序时
LD_LIBRARY_PATH都必需重新定义.
所以,事实上选择LD_LIBRARY_PATH或ldconfig没有什么不同,只是取决于你想使用它做什么.技术上讲,"正确"的方法是使
用/etc/ld.so.conf,但是在Linux系统上总是有多种方法取得同样的结果.