zoukankan      html  css  js  c++  java
  • linux下添加动态链接库路径、动态库加载等方法

    linux下添加动态链接库路径的方法

     
    Linux共享库路径配置

      Linux下找不到共享库文件的典型现象为明明已经安装某个软包(如libnet,MySQL),编译连接可以正常进行,但是在运行时出现如“error while loading shared libraries: libnet.so.1:cannot open shared object file :No such file or directory”的错误提示。

      原因是Linux下的共享库路径配置不正确。默认的linux共享库搜索路径为/lib和/usr/lib两个目录(不包含子目录),若共享库不在这两个路径,不能自动连接到(最典型的就是/usr/local/lib)。

    解决方法有五种:

    1,连接时使用静态库(.a文件)。在g++命令上写入该.a文件的完整路径。

    2,使用LD_LIBRARY_PATH环境变量。(临时有效,且有时候没有效果),把需要添加的路径加入到LD_LIBRARY_PATH中,注意如果多于一个要用冒号隔开。如:export LD_LIBRARY_PATH=/usr/local/lib/minigui

    3,将动态库文件复制到可以搜索到的路径(一般是系统默认的路径,如/lib、/usr/lib)里面,这样比较狠,但是可能导致一些后即问题。

    4,编译的时候设定:在编译源码的时候可以用参数:-Wl, -rpath指定动态搜索的路径即可。

    5,修改系统文件/etc/ld.so.conf,添加路径,运行ldconfig命令。

    第五种方法的说明如下:

    在/etc/ld.so.conf文件中指定了默认的动态链接库查找路径,我的/etc/ld.so.conf文件内容是这样的include /etc/ld.so.conf.d/*.conf。也就是说它间接的指定了定义路径的文件,我们只需要把需要的路径加到/etc/ld.so.conf.d目录下的任何一个文件中,再运行ldconfig就可以了,但为了容易理解,最好是找一个相关的文件,或者重新建立一个文件,把需要添加的路径写入然后运行ldconfig

    ldconfig几个需要注意的地方
    1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library会找不到
    2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到

    PS 

    1、linux库文件分为静态库和动态库两种。静态库习惯以.a 结尾,而动态库习惯以.so(shared object)结尾。而且必须以lib开头。

    2、静态库的原则是“以空间换时间”,增加程序体积,减少运行时间;

    生成:在编译时候,先生成目标文件.o,然后用ar文件对目标文件归档,生成静态库文件。

    例如:ar -rc libtest.a myalib.o (注意:ar -rc 目标 .o文件名),目标一定要以lib开头。

    3、使用时候,在链接时候,加上选项 -l 后接库文件名,注意:必须是文件名去掉后缀和lib,
    如:gcc -o main main.o -ltest 。而且-ltest必须放在main.o的后面,(规则是,越底层的库越要放在后面)。

    4、gcc的其他常用的选项,

    -c 编译成目标文件 如:gcc -c main.c 就是编译main.c成目标文件main.o

    -I 头文件的查找路径,如:gcc -c main.c -I./inc 意思是:头文件的查找路径除了默认的之外,再加上./inc目录下的。

    -L 库文件的查找路径,如:gcc -o main main.o -L./lib -ltest 说明:libtest.a 或者 libtest.so 库文件的查找路径除了默认之外,再加上./lib目录。

    -MM 导出文件的依赖关系(用#include 中的内容)如:gcc -MM main.c找出main.c的所依赖的头文件

    -o 生成最终目标

    -D宏定义 相当于在C中些语句#define ... 如:-DPI=3.14 就相当于在文件里面写语句#define PI 3.14

    5、动态库

    (1)、生成:在链接时,用如下选项:-shared -fpic 如: gcc -fpic -shared -o libtest.so myalib.c

    (2)、使用:有隐式使用和显示使用,隐式使用就是共享方式,程序一开始运行就调进去。在链接时候用如下:
    gcc -o main main.o -L./lib -ltest(像静态库的一样)

    显示使用就是在程序中用语句把动态库调进来,用系统调用:dlopen、dlsym、dlerror、dlclose函数,那样在编译链接时候,不用加上:-L./lib -ltest了。不过要使用dl*系列函数在编译链接时要加上 -ldl

    6、如果同一目录下,既有静态库也有动态库,比如libtest.a libtest.so都存在,那么dl程序(等一下介绍)就把动态库调进去,没有动态的,就找静态的。再没有,就报错。

    7、动态库的搜索路径

    dl对动态库的搜索路径如下(按顺序如下)

    a.编译目标代码时指定的动态库搜索路径;(如果要指定程序行时在./lib目录下找库文件libtest.so,命令如下:gcc -o main main.c -L./lib -ltest -Wl,-rpath ./lib) ,其中,-Wl的意思是,后面的选项直接交给ld程序处理,-rpath选项是说更改搜索路径为后面的参数./lib

    b.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

    c.配置文件/etc/ld.so.conf中指定的动态库搜索路径;(修改完文件后,用ldconfig更新)

    d.默认的动态库搜索路径/lib和/usr/lib;

    8、一些常用的命令(与库有关的)

    (1)、ld 是gcc的链接程序。

    (2)、ldd是查看可执行文件中所依赖的库的程序,比如想查main程序用到了那些动态库,可以直接
    ldd main

    (3)、ldconfig用来更新文件/etc/ld.so.conf的修改生效。

    (4)、nm用来查看.so库中的函数名字,标记是T的就是动态库里面生成的名字。如:nm /lib/libc*.so

  • 相关阅读:
    70.BOM
    69.捕获错误try catch
    68.键盘事件
    523. Continuous Subarray Sum
    901. Online Stock Span
    547. Friend Circles
    162. Find Peak Element
    1008. Construct Binary Search Tree from Preorder Traversal
    889. Construct Binary Tree from Preorder and Postorder Traversal
    106. Construct Binary Tree from Inorder and Postorder Traversal
  • 原文地址:https://www.cnblogs.com/ostin/p/9193029.html
Copyright © 2011-2022 走看看