说到和动态库查找路径相关的问题,总体上可以分为两类:
第一类:
通过源代码编译程序时出现的找不到某个依赖包的问题,而如果此时你恰好已经按照它的要求确确实实、千真万确、天地良心地把依赖库给装好了,它还给你耍混、
犯二,有一股折腾不死人不偿命的劲儿,那让人真是气儿不打一处来,如果Linux此时有头有脸,你是不是特想抽它丫两大嘴巴;
第二类:就是在运行程序的时候,明明把那个程序需要的依赖包都已经安装的妥妥的了,可运行的时候人家就告诉你说“error while loading shared libraries: libxxx.so.y: cannot open shared object file: No such file or directory”,
任凭你怎么折腾都没用。此时你要是心想“撤吧,哥们,Linux太TM欺负人了,不带这么玩儿的”,那你就大错特错了,只要你抱着“美好的事情的总会发
生”和“办法永远比问题多”的信念坚持下去,你就一定会成功。话的意思有点自欺欺人,精神鸦片的味道在里面,但确实是这么个理儿。
上
面两类问题最大的原因就是,你没弄白它们的机制和原理。你看到的只是现象,当年学马克思主义主义哲学原理的时候,老师怎么教导我们的?要透过现象看本质。
如果你把上面两中应用的原理搞清了,那问题不就自然而然的迎刃而解了么。下面咱们就一一探讨一下这两个问题,以便对新进学习Linux的朋友们起一个的参
考资料的作用。
问题1:通过源代码安装程序
通过源码包安装程序时,主要用到了“三大步”策略:configure、make和make install
。出问题最多的就是在configure阶段,很多初学者由于不知道configure的那么多参数该怎么用,所以往往为了省事,一句简单的
“./configure”下去,百分之八九十都能成功,可问题往往就出在剩下的百分之十几上面了。这让我们又一次相信了,小概率事件的发生对事情的影响
是多么的深远。在安装的configure阶段,为了检测安装安装环境是否满足,通常情况下都是通过一个叫做pkg-config的工具来检测它需要依赖
的动态库是否存在,这个工具我们在上一篇博文已经认识过了。pkg-config通常情况都是位于/usr/bin目录下,是个可执行程序。在
configure阶段,通常都会用pkg-config来判断所依赖的动态库是否存在。现在问题就是,这个工具是如何判断的呢?它的依据是什么?当这两
个问题弄明白了,真相也就大白了。
一般当我们安装完某个程序后,如果它提供了动态库的功能,在源码中都会有一个或多个以pc结尾的文件,当执行完make
install后这些pc文件拷贝到${prefix}/lib/pkgconfig这个目录里,这里的prefix就是我们在configure阶段时
通过配置参数--prefix指定的,缺省情况这个值就是/usr/local,所以这些pc文件最终会被拷贝到/usr/local/lib
/pkgconfig目录下。可能有人会问,这些pc文件有啥用呢?我们随便打开一个来瞅瞅:
[root@localhost ~]# cat /usr/local/lib/pkgconfig/librtmp.pc prefix=/usr/local exec_prefix=${prefix} libdir=${exec_prefix}/lib incdir=${prefix}/include Name: librtmp Description: RTMP implementation Version: v2.3 Requires: libssl,libcrypto URL: http://rtmpdump.mplayerhq.hu Libs: -L${libdir} -lrtmp -lz Cflags: -I${incdir} |
跟我们configure阶段相关的主要集中在Libs和Cflags两项上面,如果你此时再执行下面这两条命令,就全明白了:
[root@localhost ~]# pkg-config --cflags librtmp -I/usr/local/include [root@localhost ~]# pkg-config --libs librtmp -L/usr/local/lib -lrtmp -lz -lssl -lcrypto |
也就是说,pkg-config把我们以前需要在Makefile里指定编译和链接时所需要用到的参数从手工硬编码的模式变成了自动完成,节约了多少跨
平台移植的兼容性问题,我们是不是得感谢人家十八辈儿祖宗。假如说,如果我们将要的编译的软件包依赖librtmp这个动态库,那么此时在我系统上这个检
测就算通过了。当然这只是第一步,检测过了不一定兼容,这里我们只讨论能不能找到依赖库的问题,兼容性问题那都不是个事儿,人家要啥版本你好生伺候就是
了,这个没得商量,最好也不要商量,童叟无欺,不然后果很严重。好了,如果说找不到某个库该怎么办。前提是你确确实实已经安装了它需要的库,不用多想,原因只有一个,pkg-config找不到这个与这个库对应的pc文件。为什么会找不到呢,原因又有两点:
1、pkg-config搜索了所有它认为合适的目录都没找着这个库对应的pc文件的下落;
2、这个库在发布时根本就没有提供它的pc文件。
这里,我们严重“*、鄙视+抵制”第二种情况的软件包,而且也尽量不要它,一个出来混都不自报家门的家伙,肯定也好不到哪里去。那么,现在问题就只剩下一个了:pkg-config的查找路径是哪里?
pkg-config较老的版本里,缺省情况下会到/usr/lib/pkgconfig、/usr/loca/lib/pkgconfig、/usr
/share/pkgconfig等目录下去搜索pc文件,据我所知在0.23以及之后的版本里pkg-config的源码里已经没有关于缺省搜索路径的
任何硬编码的成分了,至于具体从哪个版本开始我也没有去追究,还望有知道的朋友分享一下。取而代之的是,当你看pkg-config的man手册时会有下
面一段话:
pkg-config retrieves information about packages from special metadata files. These files are named after the package, with the extension .pc. By default, pkg-config looks in the directory prefix/lib/pkgconfig for these files; it will also look in the colon-separated (on Windows, semicolon-separated) list of directories specified by the PKG_CONFIG_PATH environment variable. |
以及这点补充:
PKG_CONFIG_PATH A colon-separated (on Windows, semicolon-separated) list of directories to search for .pc files. The default directory will always be searched after searching the path; the default is libdir/pkg-config:datadir/pkgconfig where libdir is the libdir where pkg-config and datadir is the datadir where pkg-config was installed. |
上面提到的prefix、libdir和datadir,就是安装pkg-config时被设定好的,具体情况是:
1、如果你是通过yum和rpm包安装的
prefix=/usr
libdir=${prefix}/lib=/usr/lib
datadir=${prefix}/share=/usr/share
2、如果你是通过源码包安装的,且没有指定prefix的值(指定的情况同1)
prefix=/usr/local
libdir=${prefix}/lib=/usr/local/lib
datadir=${prefix}/share=/usr/local/share
pkg-config在查找对应软件包的信息时的缺省搜索路径已经很清楚了,有一点写错了,不是${libdir}/pkg-config,而应该是${libdir}/pkgconfig和${datadir}/pkgconfig。如果你软件包对应的pc文件都不在这两个目录下时,pkg-config肯定找不到。既然原因都已经找到了,那解决办法也就多种多样了。
方案一:我们可以在安装我们那个被依赖的软件包时,在configure阶段用--prefix参数把安装目录指定到/usr目录下;
方案二:也可以按照上面说的,通过一个名叫PKG_CONFIG_PATH的环境变量来向pkg-config指明我们自己的pc文件所在的路径,不过要注意的是PKG_CONFIG_PATH所指定的路径优先级比较高,pkg-config会先进行搜索,完了之后才是去搜索缺省路径。
前者的优点是以后再通过源码安装软件时少了不少麻烦,缺点是用户自己的软件包和系统软件混到一起不方便管理,所以实际使用中,后者用的要多一些。
方案二在实际操作中有两种实现方式:
1、针对没有root权限的情况,大多数情况都是执行:
export PKG_CONFIG_PATH=/your/local/path:$PKG_CONFIG_PATH |
然后,在configure时就绝对没问题了。
2、在用户的家目录下的.bash_profile文件里或系统文件/etc/profile的末尾添加上面一行也成,都可以。
至此,动态库查找问题的第一种情况就彻底解决了。想了解pc文件的更多细节的,可以参考http://people.freedesktop.org/~dbn/pkg-config-guide.html ; 想学习pkg-config工具更多用法的朋友建议看man手册。
问题2:程序运行时出现libxxx.so.y => not found
这种情况,在我以前的博文“Linux系统下动态库和静态库那点事儿”里已经提到一部分,这里就把它补充完整。在那篇博文里,我用的配置文件或者“ldconfig 动态库所在路径”的方式解决的,也是99%的场合下的解决办法,那是针对有root权限的用户的解决办法。没有root权限运行软件时,Linux也为我们提供了一个名为LD_LIBRARY_PATH的环境变量来解决运行时动态库查找路径的解决方案。同样地,由这个环境变量所指定的路径会被装载器/lib/ld-2.12.so优先查找,然后才是动态库库缓存文件/etc/ld.so.cache,风采瞬间就被LD_LIBRARY_PATH给抢完了,/etc/ld.so.cache表示很不高兴。针对LD_LIBRARY_PATH环境变量这种情况,绝对是临时不能再临时解决方案了,如果只是测试用,用export像解决PKG_CONFIG_PATH一样的方式干净利索就行了,千万不要在实际生产上线的运维环境里把“exportLD_LIBRARY_PATH=...” 添加到.bash_profile或者/etc/profile里,不然到时候悔得你肠子都绿了不可。
其实PKG_CONFIG_PATH和LD_LIBRARY_PATH经常被很多人误用,特别是新手们在解决问题时,也不分青红皂白,逮着了就是一顿狂export,根据实际场合,运气好了说不定问题还真就解决,点儿背了折腾一天半宿也是白忙活。其实要是留点心,还是挺容易明白的:
PKG_CONFIG_PATH从字面意思上翻译,就是“软件包的配置路径”,这不很明显了么,编译软件时如果出现找不到所依赖的动态库时都全靠PKG_CONFIG_PATH了;
LD_LIBRARY_PATH也很直白了“装载器的库路径”,LD是Loader的简写,在博文“段错误到底是何方妖孽”里我也曾提到过,在Linux系统启动一个程序的过程就叫做装载,一个程序要执行时它或多或少的会依赖一些动态库(静态编译的除外)。当你用“ldd 可执行程序名”查看一个软件启动时所依赖的动态库,如果输出项有“libxxx.so.y=> not found”一项,你这个软件100%运行不起来。
不信我们来做个试验:
[root@localhost ~]# echo $LD_LIBRARY_PATH //嘛也没有 [root@localhost ~]# ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0x00914000) libavdevice.so.54 => /usr/local/lib/libavdevice.so.54 (0x007d0000) libavfilter.so.3 => /usr/local/lib/libavfilter.so.3 (0x001f3000) libavformat.so.54 => /usr/local/lib/libavformat.so.54 (0x002b5000) libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0xb68dd000) libpostproc.so.52 => /usr/local/lib/libpostproc.so.52 (0x0083c000) libswresample.so.0 => /usr/local/lib/libswresample.so.0 (0x00a91000) libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x00d80000) libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x001a7000) libm.so.6 => /lib/libm.so.6 (0x0058b000) libpthread.so.0 => /lib/libpthread.so.0 (0x001d7000) libc.so.6 => /lib/libc.so.6 (0x005e2000) libasound.so.2 => /lib/libasound.so.2 (0x00ec5000) libdc1394.so.22 => /usr/local/lib/libdc1394.so.22 (0x00116000) librt.so.1 => /lib/librt.so.1 (0x00184000) libfreetype.so => /usr/local/lib/libfreetype.so (0x00411000) libass.so.4 => /usr/local/lib/libass.so.4 (0x0091a000) libssl.so.1.0.0 => /usr/local/lib/libssl.so.1.0.0 (0x0048c000) libcrypto.so.1.0.0 => /usr/local/lib/libcrypto.so.1.0.0 (0x00aa8000) librtmp.so.0 => /usr/local/lib/librtmp.so.0 (0x009dd000) libz.so.1 => /lib/libz.so.1 (0x0018d000) libx264.so.132 => /usr/local/lib/libx264.so.132 (0x00fb1000) libvorbisenc.so.2 => /usr/local/lib/libvorbisenc.so.2 (0x0194d000) libvorbis.so.0 => /usr/local/lib/libvorbis.so.0 (0x004e5000) libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x00799000) libtwolame.so.0 => /usr/local/lib/libtwolame.so.0 (0x0050d000) libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x0052d000) libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x00779000) libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00c94000) libmp3lame.so.0 => /usr/local/lib/libmp3lame.so.0 (0x0088c000) libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x00573000) /lib/ld-linux.so.2 (0x005c2000) libdl.so.2 => /lib/libdl.so.2 (0x001a1000) libraw1394.so.11 => /usr/local/lib/libraw1394.so.11 (0x005b5000) libfribidi.so.0 => /usr/local/lib/libfribidi.so.0 (0x007b5000) libfontconfig.so.1 => /usr/local/lib/libfontconfig.so.1 (0x007ea000) libogg.so.0 => /usr/local/lib/libogg.so.0 (0x00583000) libexpat.so.1 => /lib/libexpat.so.1 (0x00933000) |
我的系统里没有设置LD_LIBRARY_PATH环境变量,上一篇博文里编译的ffmpeg运行时依赖的非常多的动态库。现在我们把其中的一个库libmp3lame.so.0从/usr/loca/lib下移动到/opt目录里,并执行ldconfig,让libmp3lame.so.0彻底从/etc/ld.so.cache里面消失。其实libmp3lame.so.0只是libmp3lame.so.0.0.0的一个符号链接,我们真正需要移动的是后者,完了之后再执行ldd /usr/local/bin/ffmpeg时结果如下:
[root@localhost ~]# ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0x00249000) libavdevice.so.54 => /usr/local/lib/libavdevice.so.54 (0x00e12000) libavfilter.so.3 => /usr/local/lib/libavfilter.so.3 (0x00ccd000) libavformat.so.54 => /usr/local/lib/libavformat.so.54 (0x00891000) libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0xb6877000) libpostproc.so.52 => /usr/local/lib/libpostproc.so.52 (0x001a6000) libswresample.so.0 => /usr/local/lib/libswresample.so.0 (0x00b8f000) libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x0024a000) libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x005d7000) libm.so.6 => /lib/libm.so.6 (0x007ad000) libpthread.so.0 => /lib/libpthread.so.0 (0x001f6000) libc.so.6 => /lib/libc.so.6 (0x0029f000) libasound.so.2 => /lib/libasound.so.2 (0x00604000) libdc1394.so.22 => /usr/local/lib/libdc1394.so.22 (0x00436000) librt.so.1 => /lib/librt.so.1 (0x00a06000) libfreetype.so => /usr/local/lib/libfreetype.so (0x0052d000) libass.so.4 => /usr/local/lib/libass.so.4 (0x00211000) libssl.so.1.0.0 => /usr/local/lib/libssl.so.1.0.0 (0x00eed000) libcrypto.so.1.0.0 => /usr/local/lib/libcrypto.so.1.0.0 (0x00f46000) librtmp.so.0 => /usr/local/lib/librtmp.so.0 (0x004b9000) libz.so.1 => /lib/libz.so.1 (0x0022a000) libx264.so.132 => /usr/local/lib/libx264.so.132 (0x0765d000) libvorbisenc.so.2 => /usr/local/lib/libvorbisenc.so.2 (0x00a0f000) libvorbis.so.0 => /usr/local/lib/libvorbis.so.0 (0x004ce000) libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x005a8000) libtwolame.so.0 => /usr/local/lib/libtwolame.so.0 (0x006f0000) libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x00710000) libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x00756000) libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00770000) libmp3lame.so.0 => not found //果然飘红了 :) libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x004a4000) /lib/ld-linux.so.2 (0x0050d000) libdl.so.2 => /lib/libdl.so.2 (0x0023e000) libraw1394.so.11 => /usr/local/lib/libraw1394.so.11 (0x004f6000) libfribidi.so.0 => /usr/local/lib/libfribidi.so.0 (0x0078a000) libfontconfig.so.1 => /usr/local/lib/libfontconfig.so.1 (0x007d7000) libogg.so.0 => /usr/local/lib/libogg.so.0 (0x00243000) libexpat.so.1 => /lib/libexpat.so.1 (0x00806000) [root@localhost ~]# ffmpeg --help ffmpeg: error while loading shared libraries: libmp3lame.so.0: cannot open shared object file: No such file or directory //此时ffmpeg当然运行不起来 |
我们来试试LD_LIBRARY_PATH,看看好使不:
[root@localhost opt]# export LD_LIBRARY_PATH=/opt:$LD_LIBRARY_PATH [root@localhost opt]# [root@localhost opt]# ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0x00136000) libavdevice.so.54 => /usr/local/lib/libavdevice.so.54 (0x00552000) libavfilter.so.3 => /usr/local/lib/libavfilter.so.3 (0x00655000) libavformat.so.54 => /usr/local/lib/libavformat.so.54 (0x00243000) libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0xb68a7000) libpostproc.so.52 => /usr/local/lib/libpostproc.so.52 (0x00137000) libswresample.so.0 => /usr/local/lib/libswresample.so.0 (0x00187000) libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x0047e000) libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x00a9d000) libm.so.6 => /lib/libm.so.6 (0x00af9000) libpthread.so.0 => /lib/libpthread.so.0 (0x00823000) libc.so.6 => /lib/libc.so.6 (0x0083e000) libasound.so.2 => /lib/libasound.so.2 (0x0055f000) libdc1394.so.22 => /usr/local/lib/libdc1394.so.22 (0x0019e000) librt.so.1 => /lib/librt.so.1 (0x00b3c000) libfreetype.so => /usr/local/lib/libfreetype.so (0x0039f000) libass.so.4 => /usr/local/lib/libass.so.4 (0x00f67000) libssl.so.1.0.0 => /usr/local/lib/libssl.so.1.0.0 (0x00cb3000) libcrypto.so.1.0.0 => /usr/local/lib/libcrypto.so.1.0.0 (0x00d0c000) librtmp.so.0 => /usr/local/lib/librtmp.so.0 (0x0020c000) libz.so.1 => /lib/libz.so.1 (0x00c77000) libx264.so.132 => /usr/local/lib/libx264.so.132 (0x00f80000) libvorbisenc.so.2 => /usr/local/lib/libvorbisenc.so.2 (0x07c66000) libvorbis.so.0 => /usr/local/lib/libvorbis.so.0 (0x0041a000) libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x0076c000) libtwolame.so.0 => /usr/local/lib/libtwolame.so.0 (0x004fe000) libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x00717000) libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x00f0c000) libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00221000) libmp3lame.so.0 => not found //纳尼??!!! libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x00124000) /lib/ld-linux.so.2 (0x00bad000) libdl.so.2 => /lib/libdl.so.2 (0x0023b000) libraw1394.so.11 => /usr/local/lib/libraw1394.so.11 (0x007b6000) libfribidi.so.0 => /usr/local/lib/libfribidi.so.0 (0x00442000) libfontconfig.so.1 => /usr/local/lib/libfontconfig.so.1 (0x0051e000) libogg.so.0 => /usr/local/lib/libogg.so.0 (0x009f7000) libexpat.so.1 => /lib/libexpat.so.1 (0x00b60000) |
还记得上面提到了软链接么,libmp3lame.so.0就是libmp3lame.so.0.0.0的软链接,这是动态库的命名规范的一种公约,我们只要在/opt/目录下建立一个名为libmp3lame.so.0的到/opt/libmp3lame.so.0.0.0的软链接就OK了:
[root@localhost opt]# ls libmp3lame.so.0.0.0 [root@localhost opt]# ln -s libmp3lame.so.0.0.0 libmp3lame.so.0 [root@localhost opt]# ll total 316 lrwxrwxrwx. 1 root root 19 Dec 7 23:27 libmp3lame.so.0 -> libmp3lame.so.0.0.0 -rwxr-xr-x. 1 root root 321228 Dec 7 23:25 libmp3lame.so.0.0.0 [root@localhost opt]# ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0x00cc4000) libavdevice.so.54 => /usr/local/lib/libavdevice.so.54 (0x00577000) libavfilter.so.3 => /usr/local/lib/libavfilter.so.3 (0x00e3f000) libavformat.so.54 => /usr/local/lib/libavformat.so.54 (0x00202000) libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0x00f01000) libpostproc.so.52 => /usr/local/lib/libpostproc.so.52 (0x00170000) libswresample.so.0 => /usr/local/lib/libswresample.so.0 (0x00750000) libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x0035e000) libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x005ba000) libm.so.6 => /lib/libm.so.6 (0x00452000) libpthread.so.0 => /lib/libpthread.so.0 (0x001c0000) libc.so.6 => /lib/libc.so.6 (0x008c2000) libasound.so.2 => /lib/libasound.so.2 (0x0047c000) libdc1394.so.22 => /usr/local/lib/libdc1394.so.22 (0x003d6000) librt.so.1 => /lib/librt.so.1 (0x00db3000) libfreetype.so => /usr/local/lib/libfreetype.so (0x00a80000) libass.so.4 => /usr/local/lib/libass.so.4 (0x001db000) libssl.so.1.0.0 => /usr/local/lib/libssl.so.1.0.0 (0x005e7000) libcrypto.so.1.0.0 => /usr/local/lib/libcrypto.so.1.0.0 (0x00afb000) librtmp.so.0 => /usr/local/lib/librtmp.so.0 (0x00584000) libz.so.1 => /lib/libz.so.1 (0x00599000) libx264.so.132 => /usr/local/lib/libx264.so.132 (0x02bc9000) libvorbisenc.so.2 => /usr/local/lib/libvorbisenc.so.2 (0x05ccd000) libvorbis.so.0 => /usr/local/lib/libvorbis.so.0 (0x00640000) libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x00834000) libtwolame.so.0 => /usr/local/lib/libtwolame.so.0 (0x00668000) libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x00688000) libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x006ce000) libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00815000) libmp3lame.so.0 => /opt/libmp3lame.so.0 (0x00767000) //终于圆满了:) libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x006e8000) /lib/ld-linux.so.2 (0x003b6000) libdl.so.2 => /lib/libdl.so.2 (0x001f4000) libraw1394.so.11 => /usr/local/lib/libraw1394.so.11 (0x00444000) libfribidi.so.0 => /usr/local/lib/libfribidi.so.0 (0x006f8000) libfontconfig.so.1 => /usr/local/lib/libfontconfig.so.1 (0x00710000) libogg.so.0 => /usr/local/lib/libogg.so.0 (0x001f9000) libexpat.so.1 => /lib/libexpat.so.1 (0x007e3000) |
所以说,针对动态库路径查找的种种问题,无非就这么两大类,关键是找对原因,对症下药,方能药到病除。
Linux下动态库查找路径的问题的更多相关文章
-
谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH PKG_CONFIG_PATH
谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH PKG_CONFIG_PATH 转载自:http://blog.chinaunix.net/xmlrpc.ph ...
-
谈谈Linux下动态库查找路径的问题
学习到了一个阶段之后,就需要不断的总结.沉淀.清零,然后才能继续"上路".回想起自己当年刚接触Linux时,不管是用源码包编译程序,还是程序运行时出现的和动态库的各种恩恩怨怨,心里 ...
-
[转]谈谈Linux下动态库查找路径的问题
http://blog.chinaunix.net/uid-23069658-id-4028681.html 学习到了一个阶段之后,就需要不断的总结.沉淀.清零,然后才能继续“上路”.回想起自己当年刚 ...
-
转:谈谈Linux下动态库查找路径的问题
http://blog.chinaunix.net/uid-23069658-id-4028681.html 学习到了一个阶段之后,就需要不断的总结.沉淀.清零,然后才能继续“上路”.回想起自己当年刚 ...
-
Linux下动态库生成和使用
Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序.动态链接库是目标文件的集合,目标文件在动态链接库中 ...
-
深入理解LINUX下动态库链接器/加载器ld-linux.so.2
[ld-linux-x86-64.so.2] 最近在Linux 环境下开发,搞了好几天 Compiler 和 linker,觉得有必要来写一篇关于Linux环境下 ld.so的文章了,google上搜 ...
-
Linux下动态库(.so)和静态库(.a) 的区别
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.编译之后程序文件大,但加载快,隔离性也好.动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还 ...
-
LINUX下动态库及版本号控制
针对同一动态组件的不同版本链接和加载. 一.概念 DLL HELL字面意思是DLL"灾难",是由于com组件(动态库)升级引起的程序不能运行的情况 ...
-
LINUX总结第13篇:LINUX下动态库及版本号控制
感觉讲得挺详细 注: ln 命令用法 ln –s 源文件 目标文件 (目标文件即为软链接文件) 可用ls -l查看软链接文件具体指向哪个文件 目录[-] 1. File libhello.c 2. F ...
随机推荐
-
linux-linux top 命令各参数详解
简介 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. top显示系统当前的进程和其他状况,是一个动态显示过程,即可以通过用户按 ...
-
const 与 readonly知多少
原文地址: http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你cons ...
-
ym—— Android网络框架Volley(体验篇)
VolleyGoogle I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...
-
Maven简介
转载地址:http://www.cnblogs.com/itech/archive/2011/11/01/2231837.html Ant是软件构建工具,Maven的定位是软件项目管理和理解工具.Ma ...
-
SQL Server 2005 To Oracle
近期因为项目需要,将SQLServer2005转成Oracle 在这里介绍下转换步骤: 1. 准备好你要转换的数据,如图 2. 右键单击 任务/导出数据,如图 3. 执行完之后就打开选择数据源页面,填 ...
-
MVC中javascript直接调用Model
最近做一个统计页面, Model从后台已经获取了数据集合,想直接在前台展示,而这个展示是需要用js生成图表的. 控制器部分代码: public ActionResult Index() { var m ...
-
封装JDBC事务操作,执行存储过程测试
Oracle数据库端测试环境见:http://www.cnblogs.com/yshyee/p/4392328.html package com.mw.utils; import java.sql.C ...
-
js抽象类和抽象方法
js中模拟抽象类:在父类中调用一个未定义的方法,这个方法在子类中必须被实现. 1, 模拟类的工厂模式 //基类 var Class = { //基类的静态方法 creat:function(){ // ...
-
Ubuntu+OpenCV2.4.11+ CodeBlocks 配置
1.OpenCV 与 CodeBlocks 的安装都比较简单,好多教程. 参考http://www.cnblogs.com/lyutian/p/4425956.html 安装opencv. Codeb ...
-
转: 【Java并发编程】之五:volatile变量修饰符—意料之外的问题(含代码)
转载请注明出处: volatile用处说明 在JDK1.2之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的.而随着JVM的成熟和优化,现在在多线程 ...