Linux下编译C程序常见文件:.a .o .so .ls
虽然Linux下的文件类型不依赖于文件后缀,但通常来说:
文件后缀 | 说明 |
.o | 目标文件,相当于windows下的.obj |
.so | 共享库,是shared object,用于动态连接的,和dll差不多 |
.a | 静态库,是好多个.o合在一起,用于静态连接 |
.la | .la为libtool自动生成的一些共享库,vi编辑查看,主要记录了一些配置信息 |
下面重点说一下动态链接库.so
1. 如何创建动态链接库
假设需要把HeadA.h, HeadB.h SourceA.cpp SourceB.cpp 等若干C++文件编译成libtest.so, 执行命令:
g++ HeadA.h HeadB.h SourceA.cpp SourceB.cpp -fPIC -shared -o libtest.so
其中:
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的
-shared:该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
2.使用动态链接库
假设main.cpp中调用了HeadA.h HeadB.h中的方法。
g++ main.cpp -L. -ltest -o main
能够编译成功。但是执行./main后发现:
./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
为什么呢?
先这样做吧:将libtest.so拷贝到/usr/lib64/目录下。在执行./main
>>>>看到你期望的结果了吧!
原来:
在编译命令中,参数-L -l这是保证了编译程序时链接结果,但并未将.so文件“导入”到main可执行文件中。这样的话,在执行时,需要加载.so文件时,并不知道其所在路径。就出现了上述的错误。
将其编译成.a静态链接库可以避免该问题。但是... ...
PS:
解决该问题的另一途径——
是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。