zoukankan      html  css  js  c++  java
  • [转]linux下动态库安装问题

    转自:http://www.douban.com/note/207473567/

    一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如:



    tmux: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory


    原因一般有两个, 一个是操作系统里确实没有包含该共享库(lib*.so.*文件)或者共享库版本不对, 遇到这种情况那就去网上下载并安装上即可.

    另外一个原因就是已经安装了该共享库, 但执行需要调用该共享库的程序的时候, 程序按照默认共享库路径找不到该共享库文件.

    所以安装共享库后要注意共享库路径设置问题, 如下:

    1) 如果共享库文件安装到了/lib或/usr/lib目录下, 那么需执行一下ldconfig命令

    ldconfig 命令的用途, 主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下, 搜索出可共享的动态链接库(格式如lib*.so*), 进而创建出动态装入程序(ld.so)所需的连接和缓存文件. 缓存文件默认为/etc/ld.so.cache, 此文件保存已排好序的动态链接库名字列表.

    2) 如果共享库文件安装到了/usr/local/lib(很多开源的共享库都会安装到该目录下)或其它"非/lib或/usr/lib"目录下, 那么在执行ldconfig命令前, 还要把新共享库目录加入到共享库配置文件/etc/ld.so.conf中, 如下:

    # cat /etc/ld.so.conf
    include ld.so.conf.d/*.conf
    # echo "/usr/local/lib" >> /etc/ld.so.conf
    # ldconfig

    3) 如果共享库文件安装到了其它"非/lib或/usr/lib" 目录下, 但是又不想在/etc/ld.so.conf中加路径(或者是没有权限加路径). 那可以export一个全局变量LD_LIBRARY_PATH, 然后运行程序的时候就会去这个目录中找共享库.

    LD_LIBRARY_PATH的意思是告诉loader在哪些目录中可以找到共享库. 可以设置多个搜索目录, 这些目录之间用冒号分隔开. 比如安装了一个mysql到/usr/local/mysql目录下, 其中有一大堆库文件在/usr/local/mysql/lib下面, 则可以在.bashrc或.bash_profile或shell里加入以下语句即可:



    一般来讲这只是一种临时的解决方案, 在没有权限或临时需要的时候使用.

    --End--、

    error while loading shared libraries 的解决方法



    编译安装openmoko的gsmd
    #./configure
    #make
    #make install

    然后运行:
    #gsmd -s 115200 -p /dev/ttyS0
    #libgsmd-tool
    报错:error while loading shared libraries: libgsmd.so.0: cannot open shared object file: No such file or directory

    tank@debian:/usr/local/lib$ which libgsmd-tool
    /usr/local/bin/libgsmd-tool
    tank@debian:/usr/local/lib$ ldd /usr/local/bin/libgsmd-tool
    linux-gate.so.1 => (0xb7f3a000)
    libgsmd.so.0 => /usr/local/lib/libgsmd.so.0 (0xb7f26000)
    libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7dcb000)
    /lib/ld-linux.so.2 (0xb7f3b000)
    tank@debian:/usr/local/lib$
    确实依赖这个库。
    在/usr/local/lib下面找到这个库:
    tank@debian:/usr/local/lib$ ls -l
    总计 204
    drwxr-sr-x 2 root staff 4096 11-20 09:49 gsmd
    -rw-r--r-- 1 root staff 105846 11-20 09:49 libgsmd.a
    -rwxr-xr-x 1 root staff 792 11-20 09:49 libgsmd.la
    lrwxrwxrwx 1 root staff 16 11-20 09:49 libgsmd.so -> libgsmd.so.0.0.0
    lrwxrwxrwx 1 root staff 16 11-20 09:49 libgsmd.so.0 -> libgsmd.so.0.0.0
    -rwxr-xr-x 1 root staff 74400 11-20 09:49 libgsmd.so.0.0.0
    drwxr-sr-x 2 root staff 4096 11-20 09:49 pkgconfig
    drwxrwsr-x 3 root staff 4096 11-14 00:27 python2.5
    tank@debian:/usr/local/lib$


    一开始以为是编译问题,debian服务器用的是gcc4.3,同事编译使用gcc4.1.但换用gcc4.1也是不行。
    想到是链接库的过程中出错了。

    上网搜索:“error while loading shared libraries”

    解决方法:
       把libgsmd.so.0 所在lib位置加入到/etc/ld.so.conf文件当中
    只要在/etc/ld.so.conf中加入/usr/local/lib这一行,就可以解決此问题,不仅仅是对于libreadline.so.5,大部分的so都存在

    这/usr/local/lib这个目录里面。
    最后将/etc/ld.so.conf保存后,还要执行ldconfig 才会使更改生效

    ++++++++++++++++++++++++++++++++++++++++

    下面转帖网上的笔记,谢谢原创。
    http://hi.baidu.com/wanyinglong/blog/item/1ba5e6242228d0094d088d2b.html

    etc/ld.so.conf和ldconfig, PKG_CONFIG_PATH
    2009-04-19 22:15

    首先说下/etc/ld.so.conf:
    这个文件记录了编译时使用的动态链接库的路径。
    默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件
    如果你安装了某些库,比如在安装gtk -2.4.13时它会需要glib-2.0 >= 2.4.0,辛苦的安装好glib后
    没有指定 --prefix=/usr 这样glib库就装到了/usr/local下,而又没有在/etc/ld.so.conf中添加/usr/local/lib
    这个搜索路径,所以编译gtk -2.4.13就会出错了

    对于这种情况有两种方法解决:
    一:在编译glib-2.4.x时,指定安装到/usr下,这样库文件就会放在/usr/lib中,gtk就不会找不到需要的库文件了
    对于安装库文件来说,这是个好办法,这样也不用设置PKG_CONFIG_PATH了 (稍后说明)

    二:将/usr/local/lib加入到/etc/ld.so.conf中,这样安装gtk时就会去搜索/usr/local/lib,同样可以找到需要的库
    将/usr/local/lib加入到/etc/ld.so.conf也是必须的,这样以后安装东东到local下,就不会出现这样的问题了。
    将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择 ^_^

    添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:
    include /etc/ld.so.conf.d/*.conf
    添加一行:
    /usr/local/lib

    注:我在ld.so.conf.d 目录下的可以看到:
    tank@debian:/etc/ld.so.conf.d$ vi libc.conf

    1 # libc default configuration
    2 /usr/local/lib
    也就是说这个路径已经有了为何还要在/etc/ld.so.conf里添加?是否我只需要运行ldconfig。

    再来看看ldconfig是个什么东东吧 :
    它是一个程序,通常它位于/sbin下,是root用户使用的东东。具体作用及用法可以man ldconfig查到
    简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件 缓存到/etc/ld.so.cache 以供使用
    因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下/sbin/ldconfig
    使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用的,结果
    编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。 ^_^
    我曾经编译KDE时就犯过这个错误,(它需要每编译好一个东东,都要运行一遍),所以
    切记改动库文件后一定要运行一下ldconfig,在任何目录下运行都可以。


    再来说说 PKG_CONFIG_PATH这个变量吧:
    经常在论坛上看到有人问"为什么我已经安装了glib-2.4.x,但是编译gtk -2.4.x 还是提示glib版本太低阿?
    为什么我安装了glib-2.4.x,还是提示找不到阿?。。。。。。"都是这个变量搞的鬼。

    先来看一个编译过程中出现的错误 (编译gtk -2.4.13):
    checking for pkg-config... /usr/bin/pkg-config
    checking for glib-2.0 >= 2.4.0 atk >= 1.0.1 pango >= 1.4.0... Package glib-2.0 was not found in the pkg-config

    search path.
    Perhaps you should add the directory containing `glib-2.0.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'glib-2.0' found
    configure: error: Library requirements (glib-2.0 >= 2.4.0 atk >= 1.0.1 pango >= 1.4.0) not met; consider adjusting

    the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find

    them.


    很明显,上面这段说明,没有找到glib-2.4.x,并且提示应该将glib-2.0.pc加入到PKG_CONFIG_PATH下。
    究竟这个pkg-config PKG_CONFIG_PATH glib-2.0.pc 是做什么的呢? let me tell you ^_^

    先说说它是哪冒出来的,当安装了pkgconfig-x.x.x这个包后,就多出了pkg-config,它就是需要PKG_CONFIG_PATH的东东
    pkgconfig-x.x.x又是做什么的? 来看一段说明:
    The pkgconfig package contains tools for passing the include path and/or library paths to build tools during the

    make file execution.
    pkg-config is a function that returns meta information for the specified library.
    The default setting for PKG_CONFIG_PATH is /usr/lib/pkgconfig because of the prefix we use to install pkgconfig.

    You may add to PKG_CONFIG_PATH by exporting additional paths on your system where pkgconfig files are

    installed. Note that PKG_CONFIG_PATH is only needed when compiling packages, not during run-time.
    我想看过这段说明后,你已经大概了解了它是做什么的吧。

    其实pkg-config就是向configure程序提供系统信息的程序,比如软件的版本啦,库的版本啦,库的路径啦,等等
    这些信息只是在编译其间使用。你可以 ls /usr/lib/pkgconfig 下,会看到许多的*.pc,用文本编辑器打开
    会发现类似下面的信息:
    prefix=/usr
    exec_prefix=$
    libdir=$/lib
    includedir=$/include
    glib_genmarshal=glib-genmarshal
    gobject_query=gobject-query
    glib_mkenums=glib-mkenums
    Name: GLib
    Description: C Utility Library
    Version: 2.4.7
    Libs: -L$ -lglib-2.0
    Cflags: -I$/glib-2.0 -I$/glib-2.0/include
    明白了吧,configure就是靠这些信息判断你的软件版本是否符合要求。并且得到这些东东所在的位置,要不去哪里找呀。
    不用我说你也知道为什么会出现上面那些问题了吧。

    解决的办法很简单,设定正确的PKG_CONFIG_PATH,假如将glib-2.x.x装到了/usr/local/下,那么glib-2.0.pc就会在
    /usr/local/lib/pkgconfig下,将这个路径添加到PKG_CONFIG_PATH下就可以啦。并且确保configure找到的是正确的
    glib-2.0.pc,就是将其他的lib/pkgconfig目录glib-2.0.pc干掉就是啦。(如果有的话 ^-^)

    设定好后可以加入到~/.bashrc中,例如:
    PKG_CONFIG_PATH=/opt/kde-3.3.0/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/pkgconfig:
    /usr/X11R6/lib/pkgconfig
    [root@NEWLFS ~]#echo $PKG_CONFIG_PATH
    /opt/kde-3.3.0/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/pkgconfig:/usr/X11R6/lib/pkgconfig

    从上面可以看出,安装库文件时,指定安装到/usr,是很有好处的,无论是/etc/ld.so.conf还是PKG_CONFIG_PATH
    默认都会去搜索/usr/lib的,可以省下许多麻烦,不过从源码包管理上来说,都装在/usr下
    管理是个问题,不如装在/usr/local下方便管理
    其实只要设置好ld.so.conf,PKG_CONFIG_PATH路径后,就OK啦 ^_^

  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/pengzhiwei/p/3131972.html
Copyright © 2011-2022 走看看