注意:Linux 静态编译时将动态库也编入文件中。 文件预览 文件目录树如下,如你所见,非常简单。 1. libtest/ 2. |-- lt.c 3. |-- lt.h 4. `-- test.c 代码 #lt.c 1. /* lt.c 2. * 3. */ 4. 5. #include 6. 7. void myprint(void) 8. { 9. printf("Linux library test!\n"); 10. } # lt.h 1. /* lt.h 2. * 3. */ 4. 5. void myprint(void); #test.c 1. /* test.c 2. * 3. */ 4. 5. #include "lt.h" 6. 7. int main(void) 8. { 9. myprint(); 10. return 0; 11. } 先看静态库 首先做成静态库 liblt.a 。 1. $ gcc -o lt.o -c lt.c 2. $ ar cqs liblt.a lt.o 再者,链接, 1. $ gcc test.o liblt.a -o test 这个时候再来看他的引用库情况。 1. $ ldd test 2. linux-gate.so.1 => (0xffffe000) 3. libc.so.6 => /lib/libc.so.6 (0xb7e29000) 4. /lib/ld-linux.so.2 (0xb7f6e000) 动态库 做成动态库 liblt.so 。 1. $ gcc -o lt.o -c lt.c 2. $ gcc -shared -Wall -fPIC -o liblt.so lt.o -shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件 -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。 -L.:表示要连接的库在当前目录中 -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称 LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。 链接方法I,拷贝到系统库里再链接,让gcc自己查找 1. $ sudo cp liblt.so /usr/lib 2. $ gcc -o test test.o -llt 这里我们可以看到了 -llt 选项,-l[lib_name] 指定库名,他会主动搜索 lib[lib_name].so。这个搜索的路径可以通过 gcc --print-search-dirs来查找。 链接方法II,手动指定库路径 1. $ cc -o test test.o -llt -B /path/to/lib 这里的-B 选项就添加 /path/to/lib 到gcc搜索的路径之中。这样链接没有问题但是方法II中手动链接好的程序在执行时候仍旧需要指定库路径(链接和执行是分开的)。需要添加系 统变量 LD_LIBRARY_PATH : 1. $ export LD_LIBRARY_PATH=/path/to/lib 这个时候再来检测一下test程序的库链接状况(方法I情况) 1. $ ldd test 2. linux-gate.so.1 => (0xffffe000) 3. liblt.so => /usr/lib/liblt.so (0xb7f58000) 4. libc.so.6 => /lib/libc.so.6 (0xb7e28000)