首先先说明一下C链接器工作特点,其由于函数库太多,所以一般系统库中只包含一些常用库,短期看这些常用库完全够用,但长期工作后会常常组件自己的函数库。
为提升编译器速度,因向链接器提供指定额外的查询地址,在链接器中用-lxxxx指示其去libxxx.so中进行查找。如-lm的意思就是去libm中去找其用到的函数gcc xxx.c -lm,如低版本的gcc <math.h>不在常用库中,编译时需要加入-lm才会到libm中寻找<math.h>这个头文件。
如何制作一个静态链接库:
①首先新建一个.c文件,然后在其中写入希望实现的函数,这种函数和普通函数别无二致,该.c文件中无main()函数。
②新建一个.h文件,将函数原型在其中进行声明。
③写一个Makefile:
all:
gcc xxx.c -o xxx.o -c
ar -rc libxxx.a xxx.o
解释一下这两句话的意思,gcc xxx.c -o xxx.o -c 是将.c文件只进行到汇编,不进行链接,生成xxx.o文件。ar -rc libxxx.a xxx.o ar为归档器,-rc表示创建 libxxx.a为创建的归档文件名称,归档来源于xxx.o文件。
④发布时将.h文件以及.a文件一同打包。
⑤使用时将.h文件进行包含,编译时写为gcc abc.c -o ...... -lxxxx。-lxxxx中的-l为格式代表要包含lib库,lib库名字为xxxx,但是这样写编译器回到系统的lib库中进行寻找,在-lxxxx后面再加上-l编译器将会在当前目录中进行库的查找。gcc abc.c -o ...... -lxxxx -L
⑥nm指令 可以查询一个.a文件有什么.o文件函数原型是什么样。
如何制作一个动态链接库:动态链接库名为xxx.so,相当于windows里面的xxx.dll文件。
①首先新建一个.c文件,然后在其中写入希望实现的函数,这种函数和普通函数别无二致,该.c文件中无main()函数。
②新建一个.h文件,将函数原型在其中进行声明。
③写一个Makefile:
all:
gcc xxx.c -o xxx.o -c -fpic
gcc -o libxxx.so xxx.o -shared
-fpic表示将文件编译为位置无关码,-shared表示设置为共享方式。
④在用nm访问动态库时,会打印其包含的头文件符合以及文件符号,但nm访问静态链接库只会打印文件符号。
⑤链接库打包时将libxxx.sohe和xxx.h一同打包。
⑥使用时将.h文件进行包含,编译方法为gcc xxx.c -o ...... -lxxx -L。
⑦动态运行库存在一个问题,那就是能编译但不能运行,因为再运行的时候,程序会去系统库中找哪个被包含的xxx.so文件。
解决方法1:将xxx.so文件放到系统的/usr/lib下,但是系统的lib目录一般不会进行这些个人或商业的动态库的存储,久而久之存放的库越来越多容易出事。
解决方法2:使用环境变量LD_LIBRARY_PATH,系统会在访问/usr/lib之前去访问LD_LIBRARY_PATH指向的目录寻找库,找不到再去系统库中寻找。将libxxx.so放在my_lib目录则写法为:
export LD_LIBRART_PATH=$LD_LIBRART_PATH:/XXXX/XXXX/my_lib
可用echo查看LD_LIBRARY_PATH方法为echo $LD_LIBRARY_PATH。
解决方法3:使用ldconfig。将xxx.so存放的etc目录中(该方法好像只适用于ubuntu中)。
⑧适用ldd指令可以查看一个使用了共享库的程序在运行之前是否链接好了动态库。