美文网首页程序员程序员&&简书
Linux下动态链接库的使用

Linux下动态链接库的使用

作者: lingnanlu | 来源:发表于2014-07-05 16:59 被阅读607次

    在学习APUE时,使用gcc 1-5.c -o 1-5生成可执行文件时,出现如下错误:

    1-5.c:(.text+0x75): undefined reference to `err_sys'
    1-5.c:(.text+0xb9): undefined reference to `err_ret'
    1-5.c:(.text+0xf4): undefined reference to `err_sys'
    collect2: ld returned 1 exit status
    

    这是因为未找到以上三个函数的定义,此时,我们可以找到含有以上函数定义的源文件,生成动态链接库,然后生成1-5时,链接到动态链接库即可。

    以上函数在文件error.c中定义,所以,可使用以下命令生成动态链接库文件。

    gcc -shared -fPIC error.c -o liberror.so
    

    -share说明生成动态链接库,-fPIC表示生成位置无关代码,同时注意生成的动态链接库的名称格式

    此时,再生成1-5可执行文件可使用如下命令:

    gcc 1-5.c -o 1-5 -L. -lerror
    

    -L.表示链接依赖库的搜索路径包括当前文件,-lerror表示所要使用的动态链接库

    之后,如果执行生成的文件./1-5如出现错误

    ./1-5: error while loading shared libraries: liberror.so: cannot open shared object file: No such file or directory
    

    即,找不到文件liberror.so,这是为什么呢?因为程序1-5在执行时使用到了动态链接库,此时系统就要到某些目录中找,那么,系统是到哪些目录中找呢?

    通过网上搜寻,发现运行时动态链接库的搜索路径和ldconfig命令还有LD_LIBRARY_PATH环境变量有关,查找ldconfig命令的手册,找到如下说明

    ldconfig creates the necessary links and cache to  the  most  recent  shared libraries  found  in  the  directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories  (/lib  and  /usr/lib).
    
    -v     
        Verbose  mode.  Print current version number, the name of each direc-tory as it is scanned, and any links  that  are  created.   Overrides quiet mode.
    
    FILES
       /lib/ld.so          run-time linker/loader
       /etc/ld.so.conf     File containing a list of colon, space, tab, newline, or
                           comma-separated  directories  in  which  to  search  for
                           libraries.
       /etc/ld.so.cache    File  containing  an  ordered list of libraries found in
                           the directories specified in /etc/ld.so.conf, as well as
                           those found in /lib and /usr/lib.
    

    由上可知,/etc/ld.so.conf包括了搜寻所要使用到的目录,-v选项可以列出扫描的目录,使用ldconfig -v | grep ^/得到以下输出

    /usr/lib64/atlas:
    /usr/lib64/mysql:
    /usr/lib64/qt-3.3/lib:
    /usr/lib64/xulrunner:
    /lib:
    /lib64:
    /usr/lib:
    /usr/lib64:
    /lib64/tls: (hwcap: 0x8000000000000000)
    /usr/lib64/tls: (hwcap: 0x8000000000000000)
    /usr/lib64/sse2: (hwcap: 0x0000000004000000)
    

    现在我们可以知道ldconfig的搜寻目录有哪些了。

    我们可以将自己所生成的库所在路径添加到/etc/ld.so.conf文件中,再执行ldconfig,之后,系统就可以找到自己所生成的库文件了。

    另外,如果查阅man ld.so文档,发现如下信息

     LD_LIBRARY_PATH
              A  colon-separated  list  of  directories  in which to search for ELF
              libraries at execution-time.  Similar to the PATH  environment  vari-
              able.
    

    环境变量 LD_LIBRARY_PATH保存着执行时所依赖库的搜寻路径,所以,可以使用第二种方法来让系统找到自定义的动态链接库了。命令如下:

    export LD_LIBRARY_PATH="where you library locates?"
    

    One more thing

    在生成可执行文件时,我们使用gcc 1-5.c -o 1-5 -L. -lerror,其中-L.我们指明了依赖库的搜索路径,如果没有这个参数,那是否有系统默认的呢?
    答案是有的。系统有默认的依赖库的搜索路径,但是这个搜索路径是链接时依赖库的搜索路径,和上面所提到的运行时依赖库的搜索路径是不一样的。
    那么默认的链接时的搜索路径是哪些呢?
    网上找到了一些答案,担是我未找到官方文档中的一些说明 ,暂记录如下:

    • 编译的时候:gcc会去找-L
    • 再找gcc的环境变量LIBRARY_PATH
    • 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的

    通过将liberror.so文件拷贝到/usr/lib/目录下,然后使用gcc 1-5.c -o 1-5 -lerror执行成功可说明,/usr/lib/确实是默认目录之一。

    相关文章

      网友评论

        本文标题:Linux下动态链接库的使用

        本文链接:https://www.haomeiwen.com/subject/zgpdtttx.html