症状

新写的C++程序,在开发机上运行良好,但移置到一台全新的机器后,连接共享库失败,具体信息如下:

atp@YFCS-4-DBWAS:/data/atp/dispatcher/bin> ./dispatcher
./dispatcher: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file: No such file or directory
atp@YFCS-4-DBWAS:/data/atp/dispatcher/bin> ldd dispatcher 
 把脉

程序连接共享库失败,那得先判断该程序使用到哪些动态连接库,比较好的工具是ldd,检查如下:

atp@YFCS-4-DBWAS:/data/atp/dispatcher/bin> ldd dispatcher 
        libmysqlclient.so.18 => not found
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002ace3fcab000)
        libm.so.6 => /lib64/libm.so.6 (0x00002ace3fea9000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002ace3ffff000)
        libc.so.6 => /lib64/libc.so.6 (0x00002ace4010c000)
        /lib64/ld-linux-x86-64.so.2 (0x00002ace3fb8f000)

 库文件在连接(静态库和动态库)和运行(仅限于使用动态库的程序)时被使用,其搜索路径是在系统中进行设置的。一般linux系统把/lib和/usr/lib作为默认的库搜索路径,处于默认库搜索路径之外的库,需要用户将库位置添加到库的搜索路径之中。

由于新的机器,mysql数据库是源代码安装的,相关路径都是在configure时由-prex指定的,库文件并不在默认的库搜索路径当中,所以程序启动时连接不到对应的动态库,造成程序启动失败。

开药

经百度,发现linux系统的一个环境变量LD_LIBRARY_PATH,是用于指定查找动态库(共享库或者动态链接库)时除了默认路径之外的其它路径。(该路径在默认路径之前查找)

移植程序时的经常碰到需要使用一些特定的动态库,而这些编译好的动态库放在我们自己建立的目录里,这时可以将这些目录设置到LD_LIBRARY_PATH中。

所以,解决方案出来了,只要将libmysqlclient.so.18所在的路径添加到环境变量LD_LIBRARY_PATH即可。设置环境变量的方法可以参考:http://www.cnblogs.com/sslizy/articles/4207800.html

题外1

由于一台机器,同一个程序,可能会安装多个版本,每个版本都有自己的动态库,如果直接将某个版本的库路径直接在~/.profile或者~/.bashrc中的LD_LIBRARY_PATH设定,可能会造成其它程序启动失败。

所以,建议在程序启动的脚本中重新设置LD_LIBRARY_PATH,避免程序链接到其它动态库,造成各种诡异的结果或者意外崩溃,或者其它可能存在的安全问题。

题外2

网上,有些同行,提供另外一个解决方案,该方法是:

修改/etc/ld.so.conf文件,将自己用到的库的搜索路径(绝对路径)都添加上去,一行一个。例如:

 /usr/X11R6/lib

 /usr/local/lib

 /opt/lib

然后,再运行/sbin/ldconfig命令,以更新/etc/ld.so.config文件。

 但个人不大建议采取这样的方法,理由如下:

1、需求root权限

2、多个版本的程序,不同版本的库,可能会影响到其它程序(兼容性)

3、当系统重新启动后,所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+ 版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。

posted on 2015-01-07 16:58  Ulric.li  阅读(2735)  评论(0编辑  收藏  举报