linux下根文件系得统制作工具。内带shell命令
源代码在线查看: unix系统开发-链接程序搜索目录.txt
UNIX系统开发-链接程序搜索目录
上一节我们提到,当待于程序链接的库文件不在系统的标准位置时,需要在cc命令行中加上-L选项以指定非标准的库文件所在的目录。链接程序将首先在-L选项指定的各目录中搜索-l选项指定的库文件。在查找这些库文件时链接程序,首先看有没有指定库的动态版本,有的话则进行动态链接;否则它将用指定库的静态版本进行静态链接。
另外,前面还介绍过-dn选项,该选项使得链接程序取消缺省的动态链接方式而用静态链接。现在自然而然地产生一个问题;如何让链接程序对某些库进行静态链接而对另外一些库使用动态链接?
解决这个问题的第一种方法就是将静态库同动态库分别存放到不同的目录下。然后再cc命令行中用-L选项指定待链接的静态库所在地目录。例如,假定我们将上一节生成的静态库libtest.a放到目录$HOME/archive目录下,此时为了使myprog.c同此静态库相链接,可使用如下命令:
$ cc -L #HOME/archive -o myprog myprog.c -l test
这样,即使在命令行中因要链接$HOME/lib目录下的其他库而指定-L $HOME/lib目录,链接程序也将先在$HOME/archive目录下找到libtest.a库,此时它将进行静态链接。即使后来搜索$HOME/lib目录找到libtest.so,但也"为时已晚"。
当然这种方法要将动态库和静态库分开存放,显得有点乱。并且在某些情况下也不是总能解决问题。例如假定$HOME/archive目录下还有另外一个静态库libtest.a,并且在$HOME/lib目录下还有该库文件的一个动态版本。假设我们需对libtest.a进行静态链接而对libtest2.a进行动态链接。采用上述的方法显然就达不到目的了。如果就是要使用此种方法,那么就只好再建新目录存放libtest2.a,但这显然是比较麻烦的。
为了解决这个问题,在cc命令行中提供了-B static和-B dynamic这两个选项以取消或转向动态链接。例如,假定libtest.a仍在$HOME/lib目录下,下列命令:
$ cc -L $ HOME/lib -o myprog myprog.c -Bstatic -l test -Bdynamic
使得链接程序将myprog静态地与libtest.a相链而动态地与libc.so相链接(-lc最缺省的且位于最后)。
-Bdynamic将使链接程序不使用其后用-l选项指定的库的动态版本进行链接,而-Bdynamic选项则取消此种设定。在cc命令行中-Bstatic和-Bdynamic可以交替地使用,以获得所期望的链接效果。
增加链接程序搜索目录的另外一种方法是使用环境变量LD_LIBRARY_PATH。在此环境变量中所记录的是一系列路径的名称,如同PATH环境变量那样。如我们可以如下定义LD_LIBRARY_PATH 的值:
$ LD_LIBRARY_PATH=dir1:dir2:dir3;dir4:dir5
$ export LD_LIBRARY_PATH
我们看到LD_LIBRARY_PATH记录的值得形式同PATH变量类似:由冒号分隔的一系列路径名。所不同的只是其中可以用一个分号(;)将各路径名分成前后两个部分。分号之前的各个目录将被链接程序在-L指定的路径之前被搜索;而分号之后的各路径则在-L指定的路径之后被搜索。当然用分号将路径两部分并不是必须的。
在使用了LD_LIBRARY_PATH环境变量的值之后,链接程序将搜索的库文件目录就极大地扩展了。在链接时,首先链接程序将在LD_LIBRARY_PATH中分号之前的各目录中;然后在命令行中由-L选项指定的各目录中;再在LD_LIBRARY_PATH中分号之后的各目录中;最后再系统的标准位置搜索由-l选项指定的各个库文件。应该主要的是,在设置LD_LIBRARY_PATH的值时,必须使用绝对路径。
LD_LIBRARY_PATH还有其他的用处。下一节我们将介绍这一点。