`
灵动的水
  • 浏览: 194539 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Linux 静态库和共享库定位

阅读更多
库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:
在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。
在 /etc/ld.so.conf 文件中添加库的搜索路径。
将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择
添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:
/usr/X11R6/lib

/usr/local/lib

/opt/lib
        需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所以是直接读取库列表文件 /etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root 权限执行)。

        因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中进行了库搜索路径的设置之后,还必须要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件之后才可以。ldconfig ,简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache 以供使用。因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下 /sbin/ldconfig使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。

        在程序连接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式之外,还可以通过 -L 参数显式指定。因为用 -L 设置的路径将被优先搜索,所以在连接的时候通常都会以这种方式直接指定要连接的库的路径。
前面已经说明过了,库搜索路径的设置有两种方式:

在环境变量 LD_LIBRARY_PATH 中设置

在 /etc/ld.so.conf 文件中设置。

其中,第二种设置方式需要 root 权限,以改变 /etc/ld.so.conf 文件并执行 /sbin/ldconfig 命令。而且,当系统重新启动后,所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+ 版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。为了避免出现上面的这些情况,在 GTK+ 及其依赖库的安装过程中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要 root 权限,设置也简单:


$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH


可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容:


$ echo $LD_LIBRARY_PATH


至此,库的两种设置就完成了。




交叉编译时候如何配置连接库的搜索路径
交叉编译的时候不能使用本地(i686机器,即PC机器,研发机器)机器上的库,但是在做编译链接的时候默认的是使用本地库,即/usr/lib,/lib两个目录。因此,在交叉编译的时候,要采取一些方法使得在编译链接的时候找到需要的库。
首先,要知道:编译的时候只需要头文档,真正实际的库文档在链接的时候用到。 (这是我的理解,假如有不对的地方,敬请网上各位大侠指教) 然后,讲讲如何在交叉编译链接的时候找到需要的库。
(1)、交叉编译时候直接使用-L和-I参数指定搜索非标准的库文档和头文档的路径。例如:
arm-linux-gcc test.c -L/usr/local/arm/2.95.3/arm-linux/lib -I/usr/local/arm/2.95.3/arm-linux/include
(2)、使用ld.so.conf文档,将用到的库所在文档目录添加到此文档中,然后使用ldconfig命令刷新缓存。
(3)、使用如下命令:
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/2.95.3/arm-linux-lib
参见《ld.so.conf 文档和PKG_CONFIG_PATH变量》这篇文章。
通过环境变量LD_LIBRARY_PATH指定动态库搜索路径(!)。
通过设定环境变量LD_LIBRARY_PATH也可以指定动态库搜索路径。当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔。
不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH 的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》)。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
(4)、交叉编译时使用软件的configure参数。例如我编译minigui-1.3.3,使用如下配置:
#!/bin/bash
rm -f config.cache config.status
./configure --build=i686-linux --host=arm-linux --target=arm-linux /
CFLAGS=-I/usr/local/arm/2.95.3/arm-linux/include /
LDFLAGS=-L/usr/local/arm/2.95.3/arm-linux/lib /
--prefix=/usr/local/arm/2.95.3/arm-linux /
--enable-lite /
--disable-galqvfb /
--disable-qvfbial /
--disable-vbfsupport /
--disable-ttfsupport /
--disable-type1support /
--disable-imegb2312py /
--enable-extfullgif /
--enable-extskin /
--disable-videoqvfb /
--disable-videoecoslcd
这里我配置了CFLAGS和LDFLAGS参数,这样一来,我就不用去修改每个Makefile里-L和-I参数了,也不用再去配置LD_LIBRARY_PATH或改写ld.so.conf文档了。

Linux下动态库使用小结
1. 静态库和动态库的基本概念
静态库,是在可执行程序连接时就已经加入到执行码中,在物理上成为执行程序的一部分;使用静态库编译的程序运行时无需该库文件支持,哪里都可以用,但是生成的可执行文件较大。动态库,是在可执行程序启动时加载到执行程序中,可以被多个可执行程序共享使用。使用动态库编译生成的程序相对较小,但运行时需要库文件支持,如果机器里没有这些库文件就不能运行。
2. 如何使用动态库
如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LD_LIBRARY_PATH供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如查找/work/lib路径,你可以在/etc/rc.d/rc.local或其他系统启动后即可执行到的脚本添加如下语句:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH)。并且LD_LIBRARY_PATH路径优先于系统默认路径之前查找(详细参考《使用 LD_LIBRARY_PATH》)。
不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH 的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》)。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
3.库的链接时路径和运行时路径
现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。比如我们做嵌入式移植时#arm-linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉编译好的zlib库),将target编译好后我们只要把zlib库拷贝到开发板的系统默认路径下即可。或者通过- rpath(或-R )、LD_LIBRARY_PATH指定查找路径。
小问题:
1.编译时的-L选项是否影响LD_LIBRARY_PATH的值?
举一个实例:
当前文件夹结构如下:
test.c tools/
tool下有tool.c tool.h my_err.h 以及由此生成的libtool.so
tool下编译生成库文件
gcc -Wall -g -shared -o tool.so tool.c
在当前文件夹引用:
gcc -Wall -g –o test.c -Ltools -ltool
编译不报错,但是运行加载的时候就出现cannot open shared object file。
如果将该库文件拷贝到/usr/lib下就没有错误,正常运行。
说明编译时的-L选项并不影响环境变量LD_LIBRARY_PATH,-L只是指定了程序编译连接时库的路径,并不影响程序执行时库的路径,系统还是会到默认路径下查找该程序所需要的库。

有关动态链接库需要注意的相关事项
1.有关动态链接库需要注意的相关事项。

如果碰到有GTK 的程序中 有 <gtk/gtk.h>

那么需要加入动态链接库的参数

$ gcc test_a.c test_b.c iptbox.c -fPIC -shared -o iptbox.so `pkg-config --cflags --libs gtk+-2.0

生成出来的.so 动态链接库 需要放在usr/lib 目录下

cp libipt.so /usr/lib

2、在运行AP时出现错误,可以使用下列方式来查找问题:

strace ./test

3、查找文件夹下路径:

find /usr/lib -name libipt.so

4、解压缩命令:

tar -zxvf 文件名

5、解RPM包的方式:

#rpm -ivh scim-1.4.7.4-1benX.src.rpm

#cd /usr/src/dorado/SPECS

#rpmbuild -bb scim.spec

6、目录权限打开:

chmod 777 root(目录名称)

7、linux 下安装软件三步骤:

a.  ./configure

b.  make

c. make install

8、更新库引用:

ldconfig

9、查找是否有安装该AP.

# whereis scim-ppenglish
分享到:
评论

相关推荐

    linux静态库和动态库

    ### Linux静态库与动态库详解 #### 一、引言 在Linux环境下,库是一种重要的软件组件,用于封装一组相关的函数或数据结构,以便于在不同的应用程序之间共享代码。库通常分为两大类:静态库(static libraries)和...

    linux静态库和共享库.pdf

    在Linux操作系统中,库扮演着至关重要的角色,它们是预先编译的代码集合,允许开发者重用和集成已经实现的功能,而无需从零开始编写代码。...理解和掌握静态库与共享库的使用和管理对于任何Linux开发者都是至关重要的。

    在Linux中创建静态库和动态库

    ### 在Linux中创建静态库和动态库 #### 静态库与动态库的基本概念 在Linux环境下,库是预编译代码的集合,用于在链接阶段被其他程序使用。库分为两种类型:静态库(static libraries)和动态库(dynamic libraries...

    linux静态库及动态库创建及使用

    ### Linux静态库及动态库创建及使用 #### 一、基本概念 ##### 1.1 什么是库 在计算机编程领域,**库**(Library)是一系列预编译的代码集合,这些代码通常实现了某些功能或服务,可供其他程序在运行时调用。库可以...

    Linux下Gcc生成和使用静态库和动态库详解

    Linux下的库主要分为两种类型:静态库和共享库(动态库)。这两种类型的库的主要区别在于代码被载入的时间点不同。 - **静态库**:在编译阶段,静态库中的代码就被直接链接到了可执行程序中。这意味着最终的可执行...

    Linux静态库和动态库的制作和使用(ubuntu18.04)以及解决动态库加载失败问题

    在Linux系统中,库是程序员开发应用程序时复用代码的...同时,了解如何解决动态库加载失败的问题能帮助我们快速定位和解决问题,提高开发效率。通过实践和学习,你可以更加深入地了解这些概念并在实际项目中灵活应用。

    linux gcc生成动态库和静态库

    对于Linux平台而言,库主要分为静态库和动态库。 1.2 **库的种类** Linux下的库主要分为两种类型: - **静态库**:在编译阶段,静态库中的代码会被直接链接到最终的可执行文件中,这意味着生成的可执行文件将包含...

    liunx静态库与动态库链接装载与库.zip

    本资料主要探讨的是Linux中的静态库与动态库的链接装载过程,以及如何理解和使用它们。 静态库,通常以`.a`文件格式存在,它将所有依赖的代码直接嵌入到目标程序中。当编译程序时,链接器会将静态库中的函数和数据...

    linux系统编程-静态库-动态库-gdb调试.zip

    在Linux系统编程中,理解和掌握静态库和动态库的制作以及GDB调试是至关重要的技能。本资料包包含了关于这些主题的详细教程,通过C语言实现来帮助学习者深入理解。 首先,我们来讨论静态库。静态库是将多个目标文件...

    linux C库文件的建立和使用资料

    在Linux系统中,库文件是开发者复用代码和...总结来说,理解并熟练运用Linux下的库文件,无论是静态库还是动态库,对于C语言编程和系统级开发至关重要。掌握库的创建、使用和管理技巧,能够提高软件开发的效率和质量。

    linux静态库和动态库分析

    Linux的库分为静态库和动态库(共享库)两种,它们的使用机制和特性存在明显差异。 首先,静态库在编译时就会把库代码链接到最终生成的可执行程序中,因此生成的可执行文件会比较大。动态库则是在程序运行时才被...

    webrtc(M99) linux的 x64 静态库

    这个压缩包包含的是适用于Linux x64平台的WebRTC静态库,意味着库文件已经链接了所有必要的依赖,用户可以直接将其集成到自己的项目中,而不需要关心动态链接的问题。 1. **WebRTC架构**:WebRTC的核心组件包括 ...

    gcc静态库与动态库生成

    在嵌入式开发领域,了解如何使用gcc工具链来构建和管理静态库(`.a`文件)与动态库(`.so`文件)是非常重要的。本文将详细介绍如何通过gcc创建这两种类型的库,并讨论它们各自的用途、优缺点以及在实际项目中的应用...

    Linux平台gcc和动态共享库的基础知识 收集

    与静态库不同,动态库在程序运行时才加载到内存,这样可以减少程序的启动时间和内存占用。创建动态库时,使用`gcc -shared -o libmylib.so mylib.c`命令,其中`-shared`表示创建共享库,`-o`指定输出文件名,后跟库...

    Linux下使用动态库小结

    - **静态库**: 在编译链接阶段,静态库中的代码会被复制到可执行文件中,成为可执行文件的一部分。这意味着使用静态库编译的程序在运行时不需要外部库文件的支持,因此可以在任何地方运行。但是这种方式会导致生成的...

    共享库装载时重定位相关资料

    装载时重定位的核心优势在于它不依赖于静态分配的内存地址,而是通过动态调整内存中的地址来适应共享库的运行时需求。不过,这种技术也有一些缺点。例如,由于重定位过程发生在运行时,它可能会带来一定的性能开销。...

    Linux下的动态连接库及其实现机制.pdf

    Linux动态连接库的使用带来了诸多优势,包括代码共享、节省磁盘和内存空间,以及提高程序的可维护性。然而,这也带来了一些挑战,例如程序依赖管理、版本兼容性问题以及动态加载时的性能开销。 总结来说,Linux的...

    把 Windows 的 DLL 动态链接库在 Linux 上轻松重用起来.zip

    这可能涉及创建一个新的动态链接库或静态库,它们作为Windows DLL和Linux程序之间的桥梁。 7. **测试和调试**: 完成上述工作后,需要进行广泛的测试,确保所有功能都能正确工作。这可能涉及到在不同版本的Linux发行...

Global site tag (gtag.js) - Google Analytics