Linux下静态库,动态库的创建和使用,多个动态库使用

Linux下静态库,动态库的创建和使用,多个动态库使用

  (2009-05-19 16:09:26)
标签: 

it

分类: linux

作者:Sam(甄峰) sam_code@hotmail.com

0.介绍:

0.1 静态库:

静态库是一些目标文件的集合,通常为后缀为.o 的文件,通过ar 工具打包而成,命名
格式为libxxx.a ,其中xxx 为给定的静态库文件名。

 

在创建可执行程序的过程中,静态库同时被链接到程序代码,被主程序调用的函数目标文件连
同主程序组合成单一的可执行程序。静态库只在程序链接时起作用,最终的执行程序脱离静态
库运行。(有人说只有被调用的function和相关的内容被装载入可执行程序,但Sam试验中觉得这不一定是正确的。因为哪怕只用一个function,也产生较大的可执行文件)

 


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





Linux下静态库的创建:
gcc xxx.c -c
ar rv libxxx.a xxx.o

 

注意:不要使用 ar rv libxxx.a xxx.c

要先编译成.o文件,然后再用ar.
ar有个特点,就是如果 .c文件没编译过,它不给提示,直接将其它编译过的文件归档.

 


例如:
libBT.a: bluetooth_remote.o cmd_rpt.o AnalysisDirection.o
arm-linux-ar rv libBT.a $?
注解:
ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。

r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。

v:该选项用来显示执行操作选项的附加信息。



Linux下动态库的创建:
gcc -shared -fpic xxx.c -o libxxx.so
gcc -shared -fpic xxx.o -o libxxx.so
例如:
libBTX.so: BTX.o
$(CC) $(CFLAGS) -shared -fpic BTX.o -o libBTX.so



Linux下动态库的使用:
-lxxx
例1:某个动态库为 libBTX.so
gcc main.c -o bluetooth_test -L./ -lBTX

Linux下静态库的使用:
例2:某个静态库为 libBTX.a
gcc main.c libBTX.a -o bluetooth_test
gcc main.c -o bluetooth_test -lBTX
以上2个方法都可以链接到静态库


当几个动态库之间有依赖关系时:
例3:Sam在作libBTX.so动态库时,依赖了 libbluetooth.so这个动态库。
首先生成libBTX.so:
i686-linux-elf/bin/i686-cm-linux-gcc -D_SHOW -Wall -I../include -I/home/sam/work/current/Intel_CE_3110/Intel_Canmore/Canmore-1.1050/i686-linux-elf/include -shared -fpic BTX.o -o libBTX.so
因为依赖的是一个动态库--libbluetooth.so 所以在生成 libBTX.so时不必真的链接到libbluetooth.so

当要生成可执行文件时:
i686-linux-elf/bin/i686-cm-linux-gcc -D_SHOW -Wall -I../include -I/home/sam/work/current/Intel_CE_3110/Intel_Canmore/Canmore-1.1050/i686-linux-elf/include -L/home/sam/work/current/Intel_CE_3110/Intel_Canmore/Canmore-1.1050/i686-linux-elf/lib -L./ main.c -o BTX_Test -lpthread -lm -lBTX -lbluetooth
因为libBTX.so依赖 libbluetooth.所以需要将 libbluetooth.so也指定进来。否则libbluetooth.so所提供的function就无法找到。
注意:因为libBTX.so 依赖于libbluetooth.so.所以-lBTX 要放在 -lbluetooth之前。



静态库与动态库相依赖时与之类似。
例4:libBTX.a中依赖于libbluetooth.so
所以生成可执行文件时,也需要加入 -lbluetooth
gcc main.c -o bluetooth_test -lBTX -lbluetooth

静态库之间相互依赖:
例如,某程序需要使用 libBTX.a,libbluetooth_remote.a
则link时,需要把libbluetooth_remote.a放在libBTX.a之前。



当目录内同时存在动态库和静态库时指定使用哪个库:
-WI,-Bstatic:
这个特别的"-WI,-Bstatic"参数,实际上是传给了连接器ld。指示它与静态库连接,如果系统中只有静态库当然就不需要这个参数了。
如果某个程序需要link多个库,例如,BTX使用静态库,Bluetooth_remote使用动态库。则需要这样写:
gcc main.c -o BT_remote -WI,-Bstatic -lBTX -WI,-Bdynamic -lBluetooth_remote



编译时的 -L 选项与 环境变量 LD_LIBRARY_PATH之间的关系:
呵呵,其实他们之间没有关系,
-L 表明编译时该到什么地方去找动态,静态库。
例1:动态库libBTX.so放在 /usr/local/lib中,则 -L/usr/local/lib -lBTX
例2:动态库libBTX.so放在编译本目录中,则 -L./ -lBTX

export LD_LIBRARY_PATH则表示执行时在什么地方寻找动态库。
例3:动态库libBTX.so放在 /usr/lib/bluetooth中。则
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/bluetooth
程序执行时就会去 /usr/lib/bluetooth中寻找所需动态库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值