我之前写过一篇关于LD_LIBRARY_PATH与gcc/g++ -L的关系的文章,于是我自己用CPACK制作了一个Debian安装包,然后我在/home/.bashrc里添加了export LD_LIBRARY_PATH=/usr/loca/lib:$LD_LIBRARY_PATH,再然后老大告诉我这个方法不行,打回重新想办法,经过一番寻找终于找到了---ld.so.conf可以完美解决这个问题。

首先说说,为什么LD_LIBRARY_PATH不行?可以看看老外是怎么说的

一般LD用在下面情况:

  • 升级共享库时,替换之前先测试一下
  • 类似的,升级后的某个程序可能依赖于一些动态链接库,如果你将某个链接库替换了,程序可能就无法工作了。这时候,你可以使用LD_LIBRARY_PATH指向存有备份的一个目录,然后,你可以没有顾忌地替换系统版本了。万一出错,拷贝回去就是了

感觉LD_LIBRARY_PATH就是临时使用的,为什么呢?因为LD_LIBRARY_PATH如果设置成全局的话,如果被破坏掉的,那么就会出现大规模的破坏。不要说这个变量不会改,但是这样做就是不妥的办法,网上大家可以找到许许多多的关于LD_LIBRARY_PATH不好的文章。这里就不再多说

但是,如果不让用LD_LIBRARY_PATH,我们该怎么办呢?

Linux系统为大家已经想好了办法,我们使用ld.so.conf来解决。我们已经知道linux在加载动态库的时候,会去标准路径下(/lib,/usr/lib)下去寻找应用程序用到的动态库。但对于我们那些不标准的路径下我们安装了lib库,例如我把我的库安装到了/usr/local/lib下了,我们怎么办呢?

Linux的通常做法是:将非标准路经加入 /etc/ld.so.conf,然后运行 ldconfig 生成 ld.so.cache。 Linux在加载共享库的时候,会从 ld.so.cache 查找。[ldconfig需要在root权限下执行]

所以,我们在安装了库,但是编译程序后,ldd发现链接不到库,那么我们就要查看你安装的库是否是非标准路径,如果是那么就把你的非标准路径加入到/etc/ld.so.conf文件中,然后调用ldconfig生成下ld.so.cache,就可以了。想查看下你的库是否已经在ld.so.cache中,可以这样 ldconfig -p | grep lib**就可以了。

对于,Ubuntu来说,还与其他的LINUX系统不一样,在/etc/ld.so.conf中只有一句include /etc/ld.so.conf.d/*.conf,也就是说它我们不能在/etc/ld.so.conf下添加,但是我们可以在/etc/ld.so.conf.d下新建一个*.conf在这里面添加你的非标准路径就可以了,记得调用sudo ldconfig 生成ld.so.cache文件就可以了

补充:


说说今天又遇到的问题:(cmake之后出现的问题)

问题1:/usr/bin/ld: warning: libboost_system.so.1.55.0, need by /usr/local/lib/libboost_thread.so, may conflict with libboost_system.so.1.48.0

.....

问题2: `.text._ZN5boost16exceptions_detail10bad_alloc_D2Ev' refereced section `.text._ZN5boost16exceptions_detail10bad_alloc_D1Ev'..... of /usr/lib/gcc/x86_64-linux-gnu/4.8.2/../../../libboost_thread.a(thread.o)

这两个问题折腾我了一下午,这两个问题的变现不一样,其实他们都是一个问题造成的。

首先说说为什么会这样?

第一个问题:是由于系统里面在/usr/lib下面有一个libboost_system.so.1.48.0,而在/usr/local/lib下我安装了一个libboost_system.so.1.55.0,造成了g++链接时的冲突

第二个问题:是由于在/usr/lib下有一个libboost_thread.a,而我在/usr/local/lib下安装了libboost_thread.so.1.55.0,造成了g++链接的冲突错误。

现在问题来了,他们为什么会冲突呢?为什么呢?我们在编译程序的时候,gcc/g++是怎样搜索链接库呢?

经过仔细寻找,我们使用 ld --verbose | grep SEARCH_DIR会出现下面的内容

SEARCH_DIR("/usr/i686-linux-gnu/lib32"); SEARCH_DIR("=/usr/local/lib32"); SEARCH_DIR("=/lib32"); SEARCH_DIR("=/usr/lib32"); SEARCH_DIR("=/usr/local/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib/i386-linux-gnu"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/lib");

这就是gcc再编译的时候,所搜寻的库文件所在的路径,所以就出现了上面的问题。当gcc/g++在/usr/lib中发现这些库之后,就不再搜索了,然后就让gcc/g++链接了这些库,而我需要的正确的库应该在/usr/local/lib下,这就造成了链接了错误的库文件。

解决方法就是:删除掉/usr/lib下同名的不需要的或者版本过低的库文件(目前是这样做的,也许有更好的方法,知道的请告诉我)

上面查看gcc/g++/ld搜索路径还有其他方法:

gcc -Wl,  --verbose

gcc --print-search-dirs

有关LD_LIBRARY_PATH与ld.so.conf的更多相关文章

  1. linux环境 :Linux 共享库LIBRARY_PATH, LD_LIBRARY_PATH 与ld.so.conf

    参考: 1. Linux 共享库:LD_LIBRARY_PATH 与ld.so.conf Linux环境变量名,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径.(该路径在默 ...

  2. Linux共享库LD_LIBRARY_PATH与ld.so.conf

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

  3. 《共享库PATH与ld.so.conf简析》

    这是摘抄<共享库PATH与ld.so.conf简析>1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个 ...

  4. 转 /etc/ld.so.conf.d/目录下文件的作用

    在了解/etc/ld.so.conf.d/目录下文件的作用之前,先介绍下程序运行是加载动态库的几种方法:第一种,通过ldconfig命令    ldconfig命令的用途, 主要是在默认搜寻目录(/l ...

  5. gxx -L和/etc/ld.so.conf的理解

    编程之路刚刚开始,错误难免,希望大家能够指出. 今天编了个动态库,然后自己测试了一下. 忘记设置程序运行时系统搜索库的路径发生错误: 忘记设置程序编译的时候 -L 指定路径报的错误: -L : 告诉程 ...

  6. PKG_CONFIG_PATH变量 与 ld.so.conf 文件

    一.编译和连接 一般来说,如果库的头文件不在 /usr/include 目录中,那么在编译的时候需要用 -I 参数指定其路径.由于同一个库在不同系统上可能位于不同的目录下,用户安装库的时候也可以将库安 ...

  7. usr/bin/ld: cannot find 错误解决方法和 /etc/ld.so.conf

    我makefile出现这个错误: HelloWorldServer.c:(.text+0xaa): undefined reference to `zmq_send'collect2: error: ...

  8. /etc/ld.so.conf.d/目录下文件的作用

    在了解/etc/ld.so.conf.d/目录下文件的作用之前,先介绍下程序运行是加载动态库的几种方法: 第一种,通过ldconfig命令     ldconfig命令的用途, 主要是在默认搜寻目录( ...

  9. 转:动态库路径配置- /etc/ld.so.conf文件

    Linux 共享库 Linux 系统上有两类根本不同的 Linux 可执行程序.第一类是静态链接的可执行程序.静态可执行程序包含执行所需的所有函数 — 换句话说,它们是“完整的”.因为这一原因,静态可 ...

随机推荐

  1. Visual Studio VS如何修改代码字体

    工具-选项-环境-字体和颜色

  2. C++ std::tr1::shared_ptr使用说明

    1. 介绍 shared_ptr 是通过指针保持某个对象的共享拥有权的智能指针. 若干个 shared_ptr 对象能够拥有同一个对象:最后一个指向该对象的 shared_ptr 被销毁或重置时.该对 ...

  3. Spring中注解

    @Autowired :spring注解 @Resource :J2EE注解 @Transactional(rollbackFor=Exception.class):指定回滚 @RequestMapp ...

  4. Android:内存控制及OOM处理

      1. OOM(内存溢出)和Memory Leak(内存泄露)有什么关系? OOM可能是因为Memory Leak,也可能是你的应用本身就比较耗内存(比如图片浏览型的).所以,出现OOM不一定是Me ...

  5. Num 36 : ZOJ 2100 [ 深度优先搜索算法 ] [ 回溯 ]

    该题是用回溯法来解决的题: 题目: Seeding Time Limit: 2 Seconds      Memory Limit: 65536 KB It is spring time and fa ...

  6. string string.h cstring 区别

    c++中 string与string.h 的作用和区别 #include  <string.h>  void  main()  {        string  aaa=  "a ...

  7. 内存转储文件 Memory.dmp

    https://baike.sogou.com/v63435711.htm?fromTitle=内存转存文件 内存转储是用于系统崩溃时,将内存中的数据转储保存在转储文件中,供给有关人员进行排错分析用途 ...

  8. 在Eclipse中tomcat 内存配置

    修改1: 在Eclipse中下面Servers双击Tomcat Server... 然后点击General InformAtion 下的Open launch configuration: 会弹出Ed ...

  9. 第一个Java程序示例——Hello World!【转】

    本文转载自: 跟随世界潮流,第一个Java程序输出“Hell World!”. 通过Eclipse运行程序 启动Eclipse,在菜单中选择“文件 --> 新建 --> Java项目”,弹 ...

  10. 【转】Google 发布 Android 性能优化典范(比较老,但很实用)

    2015年伊始,Google发布了关于Android性能优化典范的专题, 一共16个短视频,每个3-5分钟,帮助开发者创建更快更优秀的Android App.课程专题不仅仅介绍了Android系统中有 ...