静态链接库
几个例子,使用和建立静态库的时候的几种常见情景。
首先建几个文件
a.h
void testA();
a.c
#include "a.h"
void testA() {
printf("A");
}
b.h
void testB();
b.c
#include "b.h"
#include "a.h"
void testB(){
testA();
printf("B");
}
- 得到目标文件
- 得到静态库文件
$gcc -c a.c
$gcc -c b.c
$ ar -r libba.a a.o b.o
$ ar -r liba.a a.o
$ ar -r libb.a b.o
得到了库libba.a libb.a liba.a
这是最终需要完成的程序。
test.c
#include "b.h"
void main()
{
testB();
}
假设我们没有a.c,b.c这两个源文件。
在这种情况下,为了编译test.c得到可执行文件,至少需要那些文件?
由于b.h中包含了a.h,所以两个头文件都是需要的。
- 用libba.a
- 用libb.a 和 liba.a
$ gcc test.c -o test -L. -lba
我们需要的是testB()和testA()的实现,libba.a里显然有这些实现,所以是可行的。
$ gcc test.c -o test -L. -lb -la
如果一开始就没有a.c,怎么办?
假设liba.a是一个第三方的闭源库,我们只有liba.a和a.h
当然,为了得到test这个可执行文件,我们也可以使用上面第二种方式编译。
如果我们不是要得到test,而是要为其它人提供libb.a怎么办?
上面的libb.a只含有testB()的实现,而没有testA()的实现。
除非“其它人”也有liba.a,否则只用libb.a是没有办法使用testB()这个函数的。
那么是不是可以把liba.a链入libb.a?
对于静态库来说,是可以的。这也就是我们的解决办法。
-r 告诉Linker进行增量式链接,得到二进制目标文件,而不是最终的可执行文件。
$ ar -r libnba.a ba.o
这个libnba.a和前面通过
$ ar -r libba.a a.o b.o
得到的libba.a应该是一样的。
这时我们就可以把libnba.a提供给”其它人”了。
$ gcc test.c -o test -L. -lnba
可以得到test可执行文件。
赞啊,之前一直没搞懂.a和.so的区别。。。
其实问题还是没有解决,我希望发布一个静态库,这个库要链接好几个动态库。User可以直接用我的静态库,而不用显式地去链接那些个动态库。貌似是不可能的…