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

在采用动态链接方式对程序进行编译,链接时候。链接程序只是在最终的可执行文件中记录下关于所引用的共享库中的符号的一些登记信息,以便在程序被执行时,动态链接程序能够根据这些登记信息找到相应的代码。因此登记动态链接方式而言,除了在链接阶段涉及到对库文件的搜索路径外,还有一个在程序运行阶段对库文件的搜索问题。

前一个问题我们知道借助于LD_LIBRARY_PATH环境变量及cc命令行中的-L选项已经得到了比较好的解决。对于第二个问题,我们必须提供一种机制,使得动态链接程序能够找到相应的动态库,然后才能将其代码映射到其自己的地址空间中。

UNIX系统中对这些问题的解决实际上采取了类似的方法。程序员可以使用LD_RUN_PATH来解决上面的第二个问题。同PATH变量相同,LD_RUN_PATH的值也是一系列由冒号分隔的绝对路径名组成的。在此环境变量中,我们可以列出所用到的动态库所在的那些目录,一般动态链接程序在程序运行时对这些目录进行搜索。例如,我们可以定义LD_RUN_PATH的值如下:

$ LD_RUN_PATH=$HOME/lib;export LD_RUN_PATH

这里我们在LD_RUN_PATH中只指定了一个目录名。在使用如下命令:

$ cc -L $HOME/lib -o myprog myprog.c -l test

建立可执行文件myprog之后,在shell提示符下输入:

$ myprog ...

在执行此程序时,动态链接程序将根据LD_RUN_PATH中所记录的路径($HOME/lib),在其中依次搜索有关的动态库libtest.so。

在搜索完LD_RUN_PATH指定的各个目录之后,动态链接程序将根据缺省设置搜索系统标准位置。对于动态链接程序而言,库的标准位置只有/usr/lib。编译系统所提供的库的每一个可执行版本都保留在/usr/lib目录中。

上一节我们介绍过的环境变量LD_LIBRARY_PATH实际上也能起到同样的作用。并且使用此环境变量还有一个好处就是在链接生成了可执行文件之后,可以把此可执行文件用到的共享库移至另一个目录中,不必重新对程序进行链接。只需恰当地设置LD_LIBRARY_PATH的值,仍然可以让动态链接程序找到相应的动态库。

仍以上例来说明这个问题。假定在生成了myprog文件之后,我们将libtest.so移至另外一个目录$HOME/sharedlib下。此时仅仅将LD_RUN_PATH的值设成是$HOME/sharedlib是不行的,因为编译产生的可执行程序将无法使用$HOME/sharedlib目录下的libtest.so。但可以在LD_LIBRARY_PATH中指定新的目录。

$LD_LIBRARY_PATH= $HOME/sharedlib;export LD_LIBRARY_PATH

这样再执行myprog时,动态链接程序将首先在$HOME/lib中搜索libtest.so。当然此时它是找不到该文件的。于是根据LD_LIBRARY_PATH的值,动态链接程序将搜索$HOME/sharedlib目录,这时它将找到所需要的库。

此种方法能够奏效是因为libtest.so的路径名在myprog中不是硬编码,所以可以在执行程序时引导动态链接程序搜索另外一个目录。也就是说,可以移动共享库而不致使引用程序无法运行,但是如果在同动态库链接时使用的是硬编码,那么就无法获得此种灵活性了。

硬编码是什么意义呢?这种做法实际上是违反cc命令行用-l指定待链接的库的约定,而直接使用库文件的全路径名进行链接。例如我们可以将myfunc.c作成一个动态链接库:

$ cc -K PIC -G -o $HOME/myfunc myfunc.c

这里生成的动态库的名称是$HOME/myfunc。由于没有遵循对动态库的命名约定,故我们想链接该库时将不能再使用-l选项的方法。而只好使用如下的“硬编码”:

$ cc -o myprog myprog.c $ HOME/myfunc

使用此种方法,编译链接也能够成功,但如果其后我们将myfunc移至另外某个目录下,则除了重新链接myprog之外别无他法。

动态链接的动态特点使得我们可以在不改变函数调用接口的前提下,对共享库的实现进行一定程度的更新,而不用重新对用到的该共享库的程序进行编译、链接。当然在动态链接库被更新之后,需要核实一下使用到该动态库的程序与新版本的兼容性,这个可以使用ldd命令来完成。

时间: 2024-09-17 19:27:33

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

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

上一节我们提到,当待于程序链接的库文件不在系统的标准位置时,需要在cc命令行中加上-L选项以指定非标准的库文件所在的目录.链接程序将首先在-L选项指定的各目录中搜索-l选项指定的库文件.在查找这些库文件时链接程序,首先看有没有指定库的动态版本,有的话则进行动态链接:否则它将用指定库的静态版本进行静态链接. 另外,前面还介绍过-dn选项,该选项使得链接程序取消缺省的动态链接方式而用静态链接.现在自然而然地产生一个问题:如何让链接程序对某些库进行静态链接而对另外一些库使用动态链接? 解决这个问题的第

第三章 装载与动态链接

装载与动态链接 1可执行文件的装载与进程 可执行文件只有装载到内存后才能被CPU执行.早期的程序装载十分简陋,装载的基本过程就是把程序从外部存储器中读取到内存中的某个位置. 历史有过的装载方式包括覆盖装载.页映射. 1.1 进程虚拟地址空间 程序是一个静态的概念,它就是一些预先编译好的指令和数据集合的一个文件:进程则是一个动态的概念,它是程序运行的一个过程. 每个程序被运行起来以后,都有自己的虚拟地址空间,这个虚拟地址空间的大小由计算机的硬件平台决定,具体地说是由CPU的位数决定的. 1.2 装

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

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

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

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

动态网页PHP程序员的优化调试技术和技巧

本文介绍调试PHP应用程序的各种方法,包括在Apache and PHP中打开错误报告,以及通过在一个简单的PHP脚本中放置策略性的print语句,找到更困难的bug的源头.还会介绍用于Eclipse的PHPEclipse插件,这是一个灵活的开发环境,具有实时语法解析能力,还会介绍PHPEclipse的DBG调试器扩展. 简介 有许多 PHP 调试技术可以在编码的时候节约大量时间.一个有效却很基本的调试技术就是打开错误报告.另一个略微高级一点的技术包括使用 print 语句,通过显示在屏幕上实际

IIs 网站应用程序与虚拟目录的区别及高级应用说明(文件分布式存储方案)

对于IIS网站,大伙用的比较多,就不啰嗦了. 今天和说说大伙比较少使用的"IIS应用程序"和虚拟目录的区别及高级应用场景,文件分布式存储方案.   1:IIS网站: 一个网站,基本就是一个站点,绑定N个域名,绑定N个IP,然后设定一个应用程序池,基本就跑起来了,一个网站可以新建无数个应用程序和虚拟目录. 一行就带过了,大伙都懂,不多说.   2:应用程序(同一域名下程序的独立开发,独立部署的最佳应用策略):   我们发现,IIS网站下,可以新建"应用程序",如下图:

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

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

动态编译JAVA程序

编译|程序|动态 在Sun JDK 1.2及后续版本中,包含了一组可在程序运行时刻编译和执行Java代码的API.这些API被包含在tools.jar类库中.这个功能允许Java程序在运行时动态编译.执行小的代码块,在有些情况下这个功能会让Java应用程序的架构更加灵活.开放. 本文假定读者已经在计算机中安装并配置好了Sun JDK 1.2或更高的版本,并对javac编译器命令有所了解. 在Java程序中使用编译器 假定要使用javac命令编译 /home/mytest目录下Test.java文

Windows7下修改程序默认安装目录

  在Windows系统中,默认程序安装路径是"C:Program Files",要安装的软件多了会导致C盘臃肿不堪,但是每次安装程序的时候手动选择安装目录又觉得十分麻烦.关于修改Windows默认安装目录的文章网上有很多,不过都是针对XP系统的,很多使用WIN7系统的朋友直接照搬过来,结果运行Win7自带的一些程序或新安装程序时会直接报错,说找不到路径等. 下面介绍下Windows7下修改程序默认安装目录的方法 1.打开注册表编辑器 在开始菜单搜索框输入 "regedit&