加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 程序设计 > 正文

多动态库依赖

发布时间:2020-05-22 16:03:23 所属栏目:程序设计 来源:互联网
导读:作者:Sam(甄峰) sam_code@hotmail.com 0.介绍: 0.1 静态库: 静态库是一些目标文件的集合,通常为后缀为.o 的文件,通过ar 工具打包而成,命名 格式为libxxx.a ,其中xxx 为给定的静态库文件名。 在创建可执行程序的过程中,静态库同时被链接到程序代码,

作者: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中寻找所需动态库。

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读