首页 » 编程笔记 » C/C++ » 正文

linux .a .o .so 文件的区别

.o 是一个最小的编译单元
.a 就是一组 .o文件打包了
.so 除了没有 main 函数,和一个可执行程类似了。

 


 

在Linux上创建静态库.a和动态库.so

我们通常把一些公用函数制作成函数库,供其它程序使用.
函数库分为静态库和共享库两种:
1.静态函数库
这类库的名字一般是libxxx.a.
利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中.
优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了.
当然这也会成为缺点,如果静态函数库改变了,那么你的程序必须重新编译.
比如PHP的configure参数–enable-mbstring=static(默认),
生成的mbstring.a被静态链接到二进制程序php,php-fpm,php-cgi,libphp.so中.
2.共享函数库
这类库的名字一般是libxxx.so.
相对于静态函数库,共享函数库在编译的时候 并没有被编译进目标代码中.
当程序执行到相关函数时才调用共享函数库里相应的函数,因此共享函数库所产生的可执行文件比较小.
由于共享函数库没有被整合进你的程序,而是在程序运行时动态地申请并调用,所以程序的运行环境中必须提供相应的库.
共享函数库的改变并不影响你的程序,所以共享函数库的升级比较方便.
比如PHP的configure参数–enable-mbstring=shared,生成的mbstring.so就是共享库.
另外用phpize生成PECL扩展库的configure文件,然后make编译,生成的也是共享库.

–enable-static 生成静态库a文件–enable-shared 生成共享库so文件

用ar打包.o文件(obj对象文件,目标文件)生成.a共享库:
ar -r libname.a name.o
ar -t libname.a 可见 name.o

 


 

.o文件
.o文件是源码编译出的二进制文件。
你先得了解从源代码到可执行文件的过程。以一个简单的add函数源文件为例。

int add(int a,int b)
{
return a+b;
}
先预处理为.i文件
gcc -E add.c -o add.i
再编译为汇编文件
gcc -S add.i -o add.s
再汇编为二进制的.o文件
gcc -c add.s -o add.o

好,现在.o文件出来了。它就是C/C++编译的产物,因为C/C++编译的单元编译。每一个.c/.cpp文件就是一个编译单元,把所有单元都编译好之后,再连接成一个完成的程序。

.a文件
.a文件实质上就是.o文件打了个包。一般把它叫做静态库文件。它在使用的时候,效果和使用.o文件是一样的。

.so文件
.so文件就不一样了,它不是简单的.o文件打了一个包,它是一个ELF格式的文件,也就是linux的可执行文件。
.so文件可以用于多个进程的共享使用(位置无关的才行),所以又叫共享库文件。程序在使用它的时候,会在运行时把它映射到自己进程空间的某一处,其不在使用它的程序中。