1. .a和.o的区别
a=archive 存档文件
o=object 对象文件
简单说.a就是将一个或多个.o封装在了一起变成了存档文件,方法为:
ar rcs libxxx.a xxx1.o xxx2.o xxx3.o
但是在使用.o和.a编译生成可执行二进制文件时,他们之间是有差别的
.o中的所有内容都会被直接编译进二进制文件中
.a中的只有被用到的.o才会被编译进二进制文件中
例如
main.c:
extern void funcInA_O1();
int main() {
func1InA_O1();
return 0;
}
object.c:
void funcInO() {
printf("This is funcInO\n");
}
ao1.c:
void func1InA_O1() {
printf("This is func1InA_O1\n");
}
void func2InA_O1() {
printf("This is func2InA_O1\n");
}
ao2.c:
void funcInA_O2() {
printf("This is funcInA_O2\n");
}
先将ao1.c和ao2.c编进.a,方法如下:
gcc -c ao1.c
gcc -c ao2.c
ar rcs libfunc.a ao1.o ao2.o
然后使用main.c和object.c编译并链接生成二进制文件,方法如下:
gcc -c main.c
gcc -c object.c
gcc main.o object.o -L . -lfunc -o excutableMain
使用readelf -s excutableMain查看其内容会发现:
1. object.o中的funcInO就算没用到,也在二进制文件中
2. 因为用到了func1InA_O1,因此libfunc.a中的ao1的内容被整个编进了二进制文件,包括没被用到的func2InA_O1(强调对.a中内容使用的最小单位是.o而不是.o中的函数;而so是按函数按需加载的)
3. 因为没用到ao2.o的任何内容,所以ao2.o不会被编进二进制文件(就算ao2.o中函数或全局变量与前面几个.o重名也不会报错)
2. 敬请期待……