假设有两个静态库,libmul.a和libadd.a。
其中libmul.a包含mul.o和mul2.o;
libadd.a里面只包含add.o。
add.c的代码如下:
int add(int a, int b)
{
return a + b;
}
mul.c的代码如下:
#include "add.h"
#include "mul.h"
int mul(int a, int b)
{
return a * b;
}
int add2(int a, int b)
{
return add(a, b);
}
mul2.c的代码如下:
#include "mul2.h"
int mul2(int a, int b)
{
return a * b;
}
add.h的内容如下:
extern int add(int,int);
mul.h的内容如下:
extern int mul(int,int);
mul2.h的内容如下:
extern int mul2(int,int);
可执行文件程序main.c的内容如下:
#include "mul.h"
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = mul(a, b);
return 0;
}
可以看到main.c里面用到的mul函数位于libmul.a库里面,位于这里面的mul.o文件的mul函数,而mul函数并没有依赖其他函数(没有依赖add.o,即没有依赖libadd.a)。
我们编译main.c如下:
可以发现,如果只链接mul静态库,报链接错误:add函数找不到实现,但是我们的main里面的调用mul并没有调用add,为何会报这种错误。
这是因为链接是以文件为单位的,mul函数的实现在mul.c里面,mul.c里面有两个函数:mul和add2,其中add2里面调用了add。在最后链接成可执行程序main的时候,由于mul函数在mul.o里面,所以需要链接mul.o。而mul.o里面的所有函数的实现都需要找到。所以需要add库。
下面是
我们再写个程序main2.c:
#include "mul2.h"
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = mul2(a, b);
return 0;
}
可以看到main2.c里面用到的mul2函数位于libmul.a库里面,位于这里面的mul2.o文件的mul2函数.
所以编译链接成最终程序main2的时候,只需要链接mul2.o,而mul2.o里面不涉及add的引用,所以不需要链接add库,如下所示:
最后,结合main和main2程序的nm结果,可以发现:最终的可执行程序里面只会包含静态库里面其依赖的.o的函数。并不是整个静态库里面的全部的.o文件里面的函数。
并且一旦依赖一个.o文件,则其包含这个.o文件里面的全部函数实现,不管程序里面是否用到所有的函数。