作者:Sam(甄峰) sam_code@hotmail.com
1.动态库和静态库的区别:
使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。
对动态库而言,就不是这样。动态库会在执行程序内留下一个标记指明当程序执行时,首先必须载入这个库。
由于动态库节省空间,Linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
Linux下静态库的创建:
ar rv libxxx.a xxx.c
ar rv libxxx.a xxx.o
例如:
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中寻找所需动态库。
没有评论:
发表评论