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还有其他的用处。下一节我们将介绍这一点。

时间: 2024-07-28 13:51:13

UNIX系统管理:链接程序搜索目录的相关文章

UNIX系统管理:动态链接程序程序搜索目录

在采用动态链接方式对程序进行编译,链接时候.链接程序只是在最终的可执行文件中记录下关于所引用的共享库中的符号的一些登记信息,以便在程序被执行时,动态链接程序能够根据这些登记信息找到相应的代码.因此登记动态链接方式而言,除了在链接阶段涉及到对库文件的搜索路径外,还有一个在程序运行阶段对库文件的搜索问题. 前一个问题我们知道借助于LD_LIBRARY_PATH环境变量及cc命令行中的-L选项已经得到了比较好的解决.对于第二个问题,我们必须提供一种机制,使得动态链接程序能够找到相应的动态库,然后才能将

UNIX系统管理:程序调试概述

对任何http://www.aliyun.com/zixun/aggregation/7298.html">程序开发而言,程序的调试都是开发过程中的一个重要阶段.程序调试的目的就是找出程序中隐藏的故障,校正那些不正常的指令,使程序能够正常工作. 程序的调试有几种不同的级别.最高级别当然是编程人员通过自己肉眼观察和推断,找出那些有毛病的代码并修改之.最低级别是对汇编代码进行调试.由于汇编语言代码的复杂.冗长与不直观.在汇编级对程序进行调试是一件比较费力的事.但UNIX得开发环境提供了汇编级的

UNIX系统管理:缺省设置,标准库函数的链接

我们已经知道链接实际上是指将在一个模块中引用的符号与它在另一个模块中的定义相链接的过程.并且我们还知道链接分为动态链接和静态链接两种方式.不论是对哪一种方式.链接程序都将搜索程序中的每一个模块,包括所用到的每一个库文件,以在这些文件中寻找在某个模块中没有定义的外部符号的定义.如果没有找到某个被引用的符号的定义,链接程序将报告错误.此时可执行文件的创建将会失败. 对于静态链接和动态链接,其区别主要在于搜索到某个符号的定义后链接程序所做的不同工作: 对静态链接,链接程序将把静态链接库(档案库)中哪些

UNIX系统管理:编译过程概述

了解一些编译知识的读者都知道,所谓编译,就是在编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序. UNIX环境下的C编译系统所遵循的也是这么一个一般的过程.值得注意的是这个过程并不是有某个单个程序完成的,而是有多个分别完成某一方面工作的程序组合完成的.这一http://www.aliyun.com/zixun/aggregation/8511.html">设计

UNIX系统管理:静态库及动态库的建立

UNIX系统及各种软件包为http://www.aliyun.com/zixun/aggregation/7155.html">开发人员提供了大量的库文件.但一般情况下这些库文件还不能足以满足用户的所有需求.开发人员大多会根据他们自己的开发.研究要求编写出许多函数.对于这些函数,如果都用在命令行中指定源文件的方法同调用它们的的程序链接起来,虽然也是可以的,但也有一些缺点: 对每一个调用了这些函数的程序,在编译时都需要将这些函数的代码分别重新编译,这实际是对计算时间的大量浪费. 一个文件中通

UNIX系统管理:sdb的启动

首先来看看在哪些情况下需要对程序进行调试. 第一种情况(这是大多数用户都会碰到的),程序在运行过程中忽然跳了出来,屏幕上显示一个xxxx-core dumped消息,然后Shell提示符就又显示出来了,其中xxxx表示出错原因.这种情况的出现一般是系统核心认为进程的执行出现了异常,如进程试图去访问一块不允许它访问的存储区域(Memory Fault,Segmentation Fault);或者扫描某个无终止符的字符串(Bus http://www.aliyun.com/zixun/aggrega

UNIX系统管理:管理文件

完成这一章,你能做以下事情:使用文件操作命令对文件进行操作. 解释排队打印队列的作用. 认识和使用 交互性的排队打印命令. 监视排队打印系统的状态.&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;1 什么是文件 一个数据的容器或者是一个设备的链接?每一个文件有一个名字,文件可能保存有存储在磁盘上的数据 ?有几种不同类别的文件: - 普通文件-?文本文件,数据文件,图片-?可执行的程序-?目录-?设备文件 UNIX系

使用Python实现跨Windows和Unix平台安装程序的方法

我们在使用类 Unix 系统时,经常会用到一些以".bin"或者".run"结尾的安装程序 (Installer).(为描述方便,这里我们使用"Bin 安装程序"来泛指这种安装程序.)Bin 安装程序不依赖于系统发行版自己的包 (package) 管理器来实现应用程序的安装和卸载,而是完全自己控制安装的整个过程,程序卸载的时候需要用户执行应用程序安装目录下的卸载脚本来完成. Bin 安装程序最大的好处就是可以运行在多种类 Unix 平台,以及基于

js实现目录链接,内容跟着目录滚动显示的简单实例_javascript技巧

如下所示: <script> require(["jquery", "bootstrap"], function($) { $(function() { $('.left').height(($('body').height() > $(window).height()) ? $('body').height() : $(window).height()); }); var goTo = $(".con"); var guide