关于GCC的头文件 动态库搜索路径

来源:互联网 发布:通联数据面试知乎 编辑:程序博客网 时间:2024/04/28 17:56

http://blog.csdn.net/diantouxiao/article/details/5836345

我们编写程序的时候会用到三个东西:头文件,链接时候库文件,运行时动态库文件。对于上面3中,我认为头文件是预处理过程的,应该和编译器有关,而链接时候库文件当然是和链接器有关了,而动态库文件时和动态装载器有关的。
制作程序时候:
头文件寻找路径问题;
1.首先从-I开始,这个是我们在编译的时候指定的
2.GCC环境变量C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH (这些变量在windows下对应的是include环境变量)
3.然后内定目录:/usr/include /prefix/include等待(prefix是我们的安装时候的目录),我们可以GCC -print-search-dirs 查看
链接时候库文件寻找路径问题;
1.首先也是寻找编译时指定的-L目录,如果不是默认链接的库文件我们还要另外指定-l选项。
2.gcc的环境变量LIBRARY_PATH
3.再找内定目录 /lib:/usr/lib: /usr/local/lib:它是制作编译器的时候写进编译器搜索路径的。gcc -print-search-dirs 可以查看。
运行程序的时候:
当然现在我们的程序已经做好了,但是现在的程序大部分是使用动态库,而动态库有分为开始执行程序时候装载库和运行程序需要的时候才装载的动态库。我们这里只讲前者搜索路径问题。我们可能碰到过运行程序的时候出现报找不到动态库的问题,LINUX下有,WINDOW下也有,这有可能就是程序需要的动态库不存在,或则没有放在指定的位置,所以找不到。
运行时动态库的搜索路径;
1、在配置文件/etc/ld.so.conf中指定动态库搜索路径
2、通过环境变量LD_LIBRARY_PATH指定动态库搜索路径(当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔)(HP-UX对应的是SHLIB_PATH环境变量,AIX对应的是LIBPATH环境变量,windows对应的是lib环境变量)
3、在编译目标代码时指定该程序的动态库搜索路径(还可以在编译目标代码时指定程序的动态库搜索路径。这是通过gcc 的参数"-Wl,-rpath,"指定。当指定多个动态库搜索路径时,路径之间用冒号":"分隔
4、默认的动态库搜索路径/lib /usr/lib
动态库的搜索路径搜索的先后顺序是:
1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib /usr/lib。
分析到这里你大概知道了相关的路径搜索了,那么你现在要做的就是把编译工具或运行工具需要的东西放在他们的搜索路径内就可以了,当然如果你考虑到执行效率的话,你还可以根据搜索顺序放在第一个搜索路径内等。(我们从路径搜索顺序来看,也发现了一个原则即用户至上的原则,即先从用户指定的目录查找然后再找别的默认目录。)不过这样比较麻烦,例如我们动态运行程序的时候一般就是修改一下LD_LIABRARY_PATH或则编译链接程序的时候-I -L选项。

http://blog.csdn.net/gogdizzy/article/details/6591267

以下是使用LD_LIBRARY_PATH的建议:
1> 不要全局设置LD_LIBRARY_PATH
2> 如果一定要用动态库的方式发布你的代码,并且允许用户自定义安装路径,那么
•用.o文件发布,在安装过程中,重新连接它们到正确的安装路径。
•在可执行程序中,写一个非常冗长,不存在的路径(-Wl,-rpath),然后安装过程中,用一个二进制编辑器将其中的路径修改为正确的。
3> 如果一定要用LD_LIBRARY_PATH,一定要包装起来用,例如,shell脚本。

 
讲一个我亲身体验的例子。

一个已经安装的软件包A,构建于平台Platform 1.0,所有的平台相关动态库文件位于/opt/lib64/
一个新的软件包B,构建于平台Platform 2.0,所有平台相关动态库位于本软件目录的/lib下
启动软件B,发现运行错误,运行ldd命令,发现连接的动态库不对,应该连本目录的lib,却连到了/opt/lib64/
用设置LD_LIBRARY_PATH的方法启动还是不行,因为路径已经写死到可执行文件里了,用strings命令可以看到二进制里的字符串。

后来查到两种解决办法:

1> 用二进制编辑器将可执行文件内的路径改写,/opt/lib64改成/opt/lib65,这样运行时找不到/opt/lib65,那么LD_LIBRARY_PATH就开始生效了。
2> 编译B之前,将configure.ac中的路径修改一下,使得传递给-Wl,-rpath的参数是一个不可能存在的路径。

原创粉丝点击