作者: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中寻找所需动态库。 (编辑:安卓应用网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|