linux库


Linux联盟收集整理 

一.库的分类

    有两种说法,如果熟悉WIN平台下的DLL,相信不难理解:


    库可以有三种使用的形式:静态、共享和动态。静态库的代码在编译时就已连接到开发人员开发的应用程序中,而共享库只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。动态库则是共享库的另一种变化形式。动态库也是在程序运行时载入,但与共享库不同的是,使用的库函数不是在程序运行开始,而是在程序中的语句需要使用该函数时才载入。动态库可以在程序运行期间释放动态库所占用的内存,腾出空间供其它程序使用。由于共享库和动态库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此代码的规模比较小。


    Linux下的库文件分为共享库和静态库两大类,它们两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。区分库类型最好的方法是看它们的文件后缀,通常共享库以.so(Shared Object的缩写)结尾,静态链接库通常以.a结尾(Archive的缩写)。在终端缺省情况下,共享库通常为绿色,而静态库为黑色。


  已经开发的大多数库都采取共享库的方式。ELF格式的可执行文件使得共享库能够比较容易地实现,当然使用旧的a.out模式也可以实现库的共享。Linux系统中目前可执行文件的标准格式为ELF格式。 

  .a的是为了支持较老的a.out格式的可执行文件的 
  .so的是支持elf格式的可执行文件的库。 


   .a是静态库文件,可以用ar 命令生成。 
  .so是动态库文件,编译时加上指定的选项即可生成,具体选项看相应的系统文档了。


二.库的命名规则
    GNU库的使用必须遵守Library GNU Public License(LGPL许可协议)。该协议与GNU许可协议略有不同,开发人员可以免费使用GNU库进行软件开发,但必须保证向用户提供所用的库函数的源代码。 


  系统中可用的库都存放在/usr/lib和/lib目录中。库文件名由前缀lib和库名以及后缀组成。根据库的类型不同,后缀名也不一样。共享库的后缀名由.so和版本号组成,静态库的后缀名为.a。采用旧的a.out格式的共享库的后缀名为.sa。 
  libname.so.major.minor 
  libname.a 


  这里的name可以是任何字符串,用来唯一标识某个库。该字符串可以是一个单字、几个字符、甚至一个字母。数学共享库的库名为libm.so.5,这里的标识字符为m,版本号为5。libm.a则是静态数学库。X-Windows库名为libX11.so.6,这里使用X11作为库的标识,版本号为6。 


三。库操作命令 


   Linux库操作可以使用命令完成,目前常用的命令是ldd和ldconfig。 


   1.ldd 
 ldd是Library Dependency Display缩写,它的作用是显示一个可执行程序必须使用的共享库。 


 $ ldd /usr/bin/mesg 
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eaf000) 
 /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7feb000) 


   2.ldconfig 
 库安装到系统以后,为了让动态链接库为系统所认识及共享,就需要运行ldconfig。ldconfig命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件。缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表,ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。 


     (1)命令格式 
 ldconfig [选项] [libs] 


     (2)主要选项 
 -v或--verbose ldconfig将显示正在扫描的目录、搜索到的动态链接库,以及它所创建的连接的名字。 


 -f CONF 指定动态链接库的配置文件为CONF,系统默认为/etc/ld.so.conf。 


 -C CACHE 指定生成的缓存文件为CACHE,系统默认的是/etc/ld.so.cache,文件存放已排好序的可共享的动态链接库的列表。 


 -p或--print-cache 让ldconfig打印出当前缓存文件所保存的所有共享库的名字。 


 -r ROOT 改变应用程序的根目录为ROOT。 


 -n ldconfig仅扫描命令行指定的目录,不扫描默认目录(/lib、/usr/lib),也不扫描配置文件/etc/ld.so.conf所列的目录。 


 运行没有选项的ldconfig命令时,用于更新高速缓冲文件。这个命令主要用于高速缓冲DNS服务器(Caching DNS Server)。高速缓冲DNS服务器的原理是提供查询的历史记录,并且利用这些记录来提高查询的效率。 


 当某个查询是第一次被发送到高速缓冲DNS服务器时,高速缓冲DNS服务器就将此查询的整个过程记录下来,在一定的时期内用它来回答所有相同的查询,从而减少整个DNS系统的负担并且提高查询速度。


四。库的升级 


 Linux系统软件更新很快,新的核心几乎每几个星期就公布一次,其它软件的更新也是非常频繁。多数情况下,盲目跟随潮流的升级并不必要,如果确实需要新版本的特性时再升级。换句话说,不要为了升级而升级。Linux系统中多数软件都是用共享库来编译的,其中包含了在不同程序之间共享的公用子例程。 


在运行某个程序时,如果看到如下信息:“Incompatible library version.”则表明需要将该库升级到程序所需要的版本。库是向下兼容的,也就是说,用老版本库编译的程序可以在新安装的版本库上运行,反之则不行。 


Linux库函数的升级是一项重要的工作,往往与其它软件包的升级有一定关联作用,所以操作前一定要备份文件。下面看一下如何把Glibc 2.2.4.13升级至2.3.2版本,其过程如下: 


  1.下载.gz压缩文件并解压 


在GUN C网站下载的四个.gz压缩文件,解压至一临时目录中: 
cd /usr/caolinux 
tar xzvf glibc-2.3.2.tar.gz 
cd glibc-2.3.2 
tar xzvf ../glibc-linuxthreads-2.3.2.tar.gz 
tar xzvf ../glibc-crypt-2.3.2.tar.gz 
tar xzvf ../glibc-localedata-2.3.2.tar.gz 


  2.建立库函数的安装目录 
mkdir /usr/higlibc 
cd /usr/higlibc 


   3.建立编译目录 
mkdir cao 
cd cao 
./configure --enable-add-ons=linuxthreads,crypt,localedata -prefix=/usr/higlibc 


  4.编译与安装 
make 
make check 
make install 


  5.改变数据库的链接 
ln -s /usr/higlibc/lib/ld-linux.so.2 /lib/ld-linux.so.2 


然后,修改/etc/ld.so.conf,加入一行/usr/higlibc/lib,执行下面代码: 
ldconfig -v 


更新/etc/ld.so.cache的内容,列出每个库的版本号,扫描目录和所要创建及更新的链接。 


 6.更改GCC设置 


cd /usr/lib/gcc-lib 
cp -r i386-redhat-linux higlibc 


 7.更新符号链接 
cd /usr/higlibc/include 
ln -s /usr/src/linux/include/linux 
ln -s /usr/src/linux/include/asm 
ln -s /usr/X11R6/include/X11 


8.测试并完成


五。高级共享库特性
 1. soname


共享库的一个非常重要的,也是非常难的概念是 soname——简写共享目标名(short for shared object name)。这是一个为共享库(.so)文件而内嵌在控制数据中的名字。如前面提到的,每一个程序都有一个需要使用的库的清单。这个清单的内容是一系列库的 soname,如同 ldd 显示的那样,共享库装载器必须找到这个清单。


soname 的关键功能是它提供了兼容性的标准。当要升级系统中的一个库时,并且新库的 soname 和老的库的 soname 一样,用旧库连接生成的程序,使用新的库依然能正常运行。这个特性使得在 Linux 下,升级使用共享库的程序和定位错误变得十分容易。 


在 Linux 中,应用程序通过使用 soname,来指定所希望库的版本。库作者也可以通过保留或者改变 soname 来声明,哪些版本是相互兼容的,这使得程序员摆脱了共享库版本冲突问题的困扰。


查看/usr/local/lib 目录,分析 MiniGUI 的共享库文件之间的关系


2. 共享库装载器


当程序被调用的时候,Linux 共享库装载器(也被称为动态连接器)也自动被调用。它的作用是保证程序所需要的所有适当版本的库都被调入内存。共享库装载器名字是 ld.so 或者是 ld-linux.so,这取决于 Linux libc 的版本,它必须使用一点外部交互,才能完成自己的工作。然而它接受在环境变量和配置文件中的配置信息。


文件 /etc/ld.so.conf 定义了标准系统库的路径。共享库装载器把它作为搜索路径。为了改变这个设置,必须以 root 身份运行 ldconfig 工具。这将更新 /etc/ls.so.cache 文件,这个文件其实是装载器内部使用的文件之一。


3. 使用 dlopen


另外一个强大的库函数是 dlopen()。该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。比如 Apache Web 服务器利用这个函数在运行过程中加载模块,这为它提供了额外的能力。一个配置文件控制了加载模块的过程。这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了。


可以在自己的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定义,并在 dl 库中实现。它需要两个参数:一个文件名和一个标志。文件名可以是我们学习过的库中的 soname。标志指明是否立刻计算库的依赖性。如果设置为 RTLD_NOW 的话,则立刻计算;如果设置的是 RTLD_LAZY,则在需要的时候才计算。另外,可以指定 RTLD_GLOBAL,它使得那些在以后才加载的库可以获得其中的符号。


当库被装入后,可以把 dlopen() 返回的句柄作为给 dlsym() 的第一个参数,以获得符号在库中的地址。使用这个地址,就可以获得库中特定函数的指针,并且调用装载库中的相应函数。


六、LINUX下动态链接库的使用 
重要的dlfcn.h头文件 
LINUX下使用动态链接库,源程序需要包含dlfcn.h头文件,此文件定义了调用动态链接库的函数的原型。下面详细说明一下这些函数。 
1。 dlerror 
原型为: const char *dlerror(void); 
当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。 
2。 dlopen 
原型为: void *dlopen (const char *filename, int flag); 
dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。 
filename: 如果名字不以/开头,则非绝对路径名,将按下列先后顺序查找该文件。 
(1) 用户环境变量中的LD_LIBRARY值; 
(2) 动态链接缓冲文件/etc/ld.so.cache 
(3) 目录/lib,/usr/lib 
flag表示在什么时候解决未定义的符号(调用)。取值有两个: 
1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。 
2) RTLD_NOW : 表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。 
dlopen调用失败时,将返回NULL值,否则返回的是操作句柄。 
3。 dlsym : 取函数执行地址 
原型为: void *dlsym(void *handle, char *symbol); 
dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。由此地址,可以带参数执行相应的函数。 
如程序代码: void (*add)(int x,int y); /* 说明一下要调用的动态函数add */ 
add=dlsym("xxx.so","add"); /* 打开xxx.so共享库,取add函数地址 */ 
add(89,369); /* 带两个参数89和369调用add函数 */ 
4。 dlclose : 关闭动态链接库 
原型为: int dlclose (void *handle); 
dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。 



linux库文件的使用和生成  

所以为了使用这些库,通常使用建立符号连接的方式。
 ln -s libhello.so.1.0 libhello.so.1 ln -s libhello.so.1 libhello.so

使用库
当 要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然 而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记‘指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的 缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。

现在假设有一个叫hello的程序开发包,它提供一个静态库libhello.a 一个动态库libhello.so,一个头文件hello.h,头文件中提供sayhello()这个函数
 /* hello.h */
 void sayhello(); 另外还有一些说明文档。这一个典型的程序开发包结构

1.与动态库连接 linux默认的就是与动态库连接,下面这段程序testlib.c使用hello库中的sayhello()函数
 /*testlib.c*/
#include
#include
 int main()
{ sayhello();
  return 0;
}

使用如下命令进行编译 $gcc -c testlib.c -o testlib.o 用如下命令连接: $gcc testlib.o -lhello -o testlib 在连接时要注意,假设libhello.o 和libhello.a都在缺省的库搜索路径下/usr/lib下。如果在其它位置要加上-L参数 。

2.与静态库连接麻烦一些,主要是参数问题。还是上面的例子: $gcc testlib.o -o testlib -WI,-Bstatic -lhello 注:这个特别的"-WI,-Bstatic"参数,实际上是传给了连接器ld. 指示它与静态库连接,如果系统中只有静态库当然就不需要这个参数了。 如果要和多个库相连接,而每个库的连接方式不一样,比如上面的程序既要和libhello进行静态连接,又要和libbye进行动态连接,其命令应为: $gcc testlib.o -o testlib -WI,-Bstatic -lhello -WI,-Bdynamic -lbye

3.动态库的路径问题 为了让执行程序顺利找到动态库,有三种方法: (1)把库拷贝到/usr/lib和/lib目录下。 (2)在LD_LIBRARY_PATH环境变量中加上库所在路径。例如动态库libhello.so在/home/ting/lib目录下,以bash为例,使用命令: $export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib (3) 修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见、

4.查看库中的符号 有 时候可能需要查看一个库中到底有哪些函数,nm命令可以打印出库中的涉及到的所有符号。库既可以是静态的也可以是动态的。nm列出的符号有很多,常见的有 三种,一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;一种是库中定义的函数,用T表示,这是最常见的;另外一种是所谓的“弱 态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。例如,假设开发者希望知道上央提到的hello库中是否定义了 printf():

$nm libhello.so |grep printf U printf

U表示符号printf被引用,但是并没有在函数内定义,由此可以推断,要正常使用hello库,必须有其它库支持,再使用ldd命令查看hello依赖于哪些库:
 $ldd hello libc.so.6=>/lib/libc.so.6(0x400la000) /lib/ld-linux.so.2=>/lib/ld-linux.so.2 (0x40000000) 从上面的结果可以继续查看printf最终在哪里被定义,有兴趣可以go on 生成库 第一步要把源代码编绎成目标代码。以下面的代码为例,生成上面用到的hello库:
 /* hello.c */
#include
void sayhello()
 { printf("hello,world "); }

用gcc编绎该文件,在编绎时可以使用任何全法的编绎参数,例如-g加入调试代码等: gcc -c hello.c -o hello.o 1.连接成静态库 连接成静态库使用ar命令,其实ar是archive的意思 $ar cqs libhello.a hello.o 2.连接成动态库 生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号: $gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o 另外再建立两个符号连接: $ln -s libhello.so.1.0 libhello.so.1 $ln -s libhello.so.1 libhello.so 这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序。 -Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。实际上,每一个库都有一个soname,当连接器发现它正 在查找的程序库中有这样一个名称,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运行的实际文件名,在程序执行期间,程序会查找拥有 soname名字的文件,而不是库的文件名,换句话说,soname是库的区分标志。 这样做的目的主要是允许系统中多个版本的库文件共存,习惯上在命名库文件的时候通常与soname相同 libxxxx.so.major.minor 其中,xxxx是库的名字,major是主版本号,minor 是次版本号



库的定义和种类


所谓编程库就是指始终可以被多个Linux软件项目重复使用的代码集。库是Linux软件开发所追求的目标,C语言就是一个例子,它包含了几百个可以重复使用的例程和调试程序的工具代码,其中包括函数。如果每次编写新程序都要重新写这些函数会感到非常麻烦。


使用编程库有两个主要优点,一是可以简化编程,实现代码重复使用;二是可以直接使用许多经过调试的测试和调试工具。


Linux下的库文件分为共享库和静态库两大类,它们两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。


Linux的库一般在/lib或/usr/lib目录下。lib是库(Library)的英文缩写,它主要存放系统的链接库文件,没有该目录则系统就无法正常运行。/lib目录中存储着程序运行时使用的共享库。通过共享库,许多程序可以重复使用相同的代码,并且这些库可以存储在一个公共的位置上,因此能减小运行程序的大小。这个目录包含程序在链接时使用的各种库。图1是笔者/usr/lib(Red Hat Linux 9.0)目录快照。












图1 /usr/lib目录快照




区分库类型最好的方法是看它们的文件后缀,通常共享库以.so(Shared Object的缩写)结尾,静态链接库通常以.a结尾(Archive的缩写)。在终端缺省情况下,共享库通常为绿色,而静态库为黑色。
库的命名和编号


在Linux下开发应用程序时,绝大多数情况使用的都是C语言,目前Linux下最常用的C语言编译器是GCC,它的全称是GNU Compiler Collection,下文中的库介绍都以它为例。


GCC是直接建立在内核基础上的,是Linux操作系统外层的图形界面开发工具(Qt、GTK+)和网络应用开发工具(PHP、Prel、Python)的基础和过渡。掌握了底层开发工具,可以加快和优化外层应用开发,从而达到开发速度和开发质量的和谐统一。


Glibc 2.3.2是最新版的GNU C库。它目前不需要修改就可以在GNU Hurd、Linux i386、m68k,以及Alpha系统上执行,并且从2.1版开始加入了对Linux PowerPC、MIPS、Sparc、Sparc 64等系统的支持。


如果想查看自己Linux计算机的Glibc版本可以使用下面命令:




rpm -qa|grep glibc
glibc-common-2.3.2-11.9
glibc-2.3.2-11.9
glibc-devel-2.3.2-11.9
 






由上可见,Red Hat Linux 9.0使用的Glibc版本是2.3.2。 


1.库的命名 


库的命名比较简单,第一个特点是所有的库以lib开头,GCC命令在在-l选项所指定的文件名前会自动加入lib。第二个特点文件名以.a结尾的库是静态库。第三个特点文件名是.so的库为共享库。默认情况下,GCC在链接时优先使用共享库,只有当共享库不存在时才考虑使用静态库。 


2.库的编号 


库的编号格式如下: 




library_name.major.num.minor_.min.pathch_num
 




例如,笔者Red Hat Linux 9.0的GUN数据库是libgdbm.so.0.0.2,详细表述如下:


◆library_name是libc.so(标准C库);


◆major_num是2(主版本号);


◆minor_.min是0(次版本号);


◆pathch_num是0(补丁级别号又称发行号)。


libgdbm.so.0.0.2所在目录是/usr/lib,其大小是24576字节,这是一个ELF(Executable and Linking Format)格式的二进制格式文件,运行时由系统将其装入内存开始执行。


ELF有三种主要类型: 


◆适于连接的可重定位文件(Relocatable File),可与其它目标文件一起创建可执行文件和共享目标文件。 


◆适于执行的可执行文件(Executable File),用于提供程序的进程映像,加载的内存执行。


◆共享目标文件(Shared Object File),连接器可将它与其它可重定位文件和共享目标文件连接成其它的目标文件;动态连接器又可将它与可执行文件和其它共享目标文件结合起来创建一个进程映像。


常用的编程库


库操作命令


Linux库操作可以使用命令完成,目前常用的命令是ldd和ldconfig。


1.ldd ldd是Library Dependency Display缩写,它的作用是显示一个可执行程序必须使用的共享库。


(1)命令格式


ldd [选项] 文件名


(2)主要参数


-d 执行重定位并报告丢失的函数。


-r 执行对函数和数据对象的重定位,并报告丢失的函数和数据对象。
(3)应用实例


Perl语言是开发者喜欢使用的一种“胶水语言”(能够将许多元素连接在一起,因此它具有极强的适应性),如果需要查询有哪些共享库,则可以首先使用find命令查询这个程序的绝对路径,然后使用ldd命令:
























#find -name perl
ldd  /usr/bin/perl
 






其结果见图2所示。图2中,箭头左边的一列显示的是Prel语言所需的.so文件名, 箭头右边的一列显示是库的真实库名称。应用程序链接到库的so名字是到实际库的符号链接。以第二行为例,最后的0x40014000是库libperl.so的加载地址。由此可以看到,运行Perl语言需要9个共享库。 












图2 运行Perl语言需要的共享库


2.ldconfig


ldconfig命令的作用是决定位于目录/usr/lib和/lib下的共享库所需的运行链接。这些链接保存在的Libs保存在/et/ld.so.conf文件中。搜索出可共享的动态链接库(格式如前介绍,lib*.so*),进而创建出动态装入程序(ld.so)所需的链接和缓存文件。缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。


(1)命令格式


















ldconfig [选项] [libs]
 






(2)主要选项 


-v或--verbose ldconfig将显示正在扫描的目录、搜索到的动态链接库,以及它所创建的连接的名字。 


-f CONF 指定动态链接库的配置文件为CONF,系统默认为/etc/ld.so.conf。 


-C CACHE 指定生成的缓存文件为CACHE,系统默认的是/etc/ld.so.cache,文件存放已排好序的可共享的动态链接库的列表。 


-p或--print-cache 让ldconfig打印出当前缓存文件所保存的所有共享库的名字。 


-r ROOT 改变应用程序的根目录为ROOT。 


-n ldconfig仅扫描命令行指定的目录,不扫描默认目录(/lib、/usr/lib),也不扫描配置文件/etc/ld.so.conf所列的目录。 


运行没有选项的ldconfig命令时,用于更新高速缓冲文件。这个命令主要用于高速缓冲DNS服务器(Caching DNS Server)。高速缓冲DNS服务器的原理是提供查询的历史记录,并且利用这些记录来提高查询的效率。 


当某个查询是第一次被发送到高速缓冲DNS服务器时,高速缓冲DNS服务器就将此查询的整个过程记录下来,在一定的时期内用它来回答所有相同的查询,从而减少整个DNS系统的负担并且提高查询速度。 


(3)应用实例 


如果用户想知道系统中有哪些动态链接库,或者想知道系统中有没有某个动态链接库时,可用-p选项让ldconfig输出缓存文件中的动态链接库列表,从而查询得到。 




ldconfig -p
998 libs found in cache `/etc/ld.so.cache'
libzvt.so.2 (libc6) => /usr/lib/libzvt.so.2
libzvt.so (libc6) => /usr/lib/libzvt.so
……
 






ldconfig命令输出结果表明,在缓存文件/etc/ld.so.cache中找到998个共享库,下一行开始便是一系列共享库的名字及其全名(绝对路径)。因为实际输出结果很多,为节省篇幅以“……”表示省略的部分。 


库的升级


Linux系统软件更新很快,新的核心几乎每几个星期就公布一次,其它软件的更新也是非常频繁。多数情况下,盲目跟随潮流的升级并不必要,如果确实需要新版本的特性时再升级。换句话说,不要为了升级而升级。Linux系统中多数软件都是用共享库来编译的,其中包含了在不同程序之间共享的公用子例程。


在运行某个程序时,如果看到如下信息:“Incompatible library version.”则表明需要将该库升级到程序所需要的版本。库是向下兼容的,也就是说,用老版本库编译的程序可以在新安装的版本库上运行,反之则不行。


Linux库函数的升级是一项重要的工作,往往与其它软件包的升级有一定关联作用,所以操作前一定要备份文件。下面看一下如何把Glibc 2.2.4.13升级至2.3.2版本,其过程如下:


1.下载.gz压缩文件并解压


在GUN C网站下载的四个.gz压缩文件,解压至一临时目录中: 




cd /usr/caolinux 
tar xzvf glibc-2.3.2.tar.gz 
cd glibc-2.3.2 
tar xzvf ../glibc-linuxthreads-2.3.2.tar.gz 
tar xzvf ../glibc-crypt-2.3.2.tar.gz 
tar xzvf ../glibc-localedata-2.3.2.tar.gz
 






2.建立库函数的安装目录 




mkdir /usr/higlibc 
cd /usr/higlibc
 






3.建立编译目录 




mkdir cao 
cd cao 
./configure --enable-add-ons=linuxthreads,crypt,localedata -prefix 
=/usr/higlibc
 






4.编译与安装 




make 
make check 
make install
 






编译与安装过程根据计算机硬件配置不同,从10分钟到几十分钟不等。 


5.改变数据库的链接 




ln -s /usr/higlibc/lib/ld-linux.so.2 /lib/ld-linux.so.2
 






然后,修改/etc/ld.so.conf,加入一行/usr/higlibc/lib,执行下面代码: 




ldconfig -v
 






更新/etc/ld.so.cache的内容,列出每个库的版本号,扫描目录和所要创建及更新的链接。 


6.更改GCC设置 




cd /usr/lib/gcc-lib 
cp -r i386-redhat-linux higlibc
 






7.更新符号链接 




cd /usr/higlibc/include 
ln -s /usr/src/linux/include/linux 
ln -s /usr/src/linux/include/asm 
ln -s /usr/X11R6/include/X11
 






8.测试 


编写一个简单的C程序测试一下,除了头文件只需一条printf语句即可: 




#include <stdio.h>
int main(void)
{ printf ("Hello , Linux !\n");
return 0;}
 






然后用GCC编译一次,当程序出现如下运行结果,则说明已经正确地升级了。 




“Hello, Linux !”
 






以上五部分分别介绍了Linux库的定义属性、“标准”库的命名和编号约定、经常使用的库、与库操作相关命令的作用,以及库升级的步骤,希望能对初学Linux的开发者有所帮助。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值