出自http://tech.it168.com/KnowledgeBase/Articles/5/e/0/5e0f35b27d205c90de00e1b6571db6fe.htm
在转这个文章的时候,我还没有测试过这个功能。只是觉的有用就拿到自己这,因为我知道有一天我会用到这东东
我在写自己的库的途中,为了读图片,又没有能力自己写,不得不用到了另外两个库(zlib和libpng), 编译出来以后给测试程序用. 麻烦的是,测试程序仍然需要添加上那两个库才能运行. 这大概是因为mingw在编译时没有自动合并库中的函数定义,而只是把函数名写进去了. 所以测试程序虽然包含了我的库,却无法找到内部用到的函数的实现.
然后我就尝试把zlib和libpng的源代码都加进来一块编译,虽然编译通过了,但测试程序根本读不出图片. 结果就又删了.
搜一了下:"合并静态库", 找到只言片语,说是用ar和nm这两个工具. 没想到真的可以! .a文件,也就是unix的库文件,大概来自archives这个词,是由各个模块的.o文件组成的. ar命令用来修改和创建库,nm用来查看库内部的.o模块. 没有一个直接的方法可以实现add x.a y.a, 来把y合并到x中的. 但这时... ar命令有一个参数-x, 用来把内部的.o模块都提取出来, 然后再用ar -r把提取出来的所有.o文件都加到主库就行了,实际操作如下:
这时目录中出现了y1.o, y2.o
ar - r x.a y1.o y2.o
没了
最后达到了不加任何连接库就可以顺利运行的效果. 但是我那小小的库被合并胖了好几倍...
这招应该同样适用于合并动态库的导入库.
这样手动太累了,碰到libopengl32.a, 提取出来360多个模块! 这下非要做个自动合并工具才行了. that's it:
# include <stdlib.h>
int main(int argn, char ** arg)
{
char str[ 256 ];
char command[ 20 ];
FILE * fp;
char * mainlib;
char * addlib;
if (argn != 3 ) {
printf ( " should be not 2 file\n " );
return 1 ;
}
mainlib = arg[ 1 ];
fp = fopen (mainlib, " r " );
if (fp == NULL) {
printf ( " error file\n " );
return 1 ;
}
fclose (fp);
addlib = arg[ 2 ];
fp = fopen (addlib, " r " );
if (fp == NULL) {
printf ( " error file\n " );
return 1 ;
}
fclose (fp);
printf ( " start to expand addlib file\n " );
sprintf (command, " ar -x %s " , addlib);
system (command);
printf ( " start to check the addlib out to a.txt \n " );
// 用ar -t显示模块名列表,保存在a.txt文件里,如果能保存在内存里就快了
sprintf (command, " ar -t %s > a.txt " , addlib);
system (command);
fp = fopen ( " a.txt " , " r " );
if (fp == NULL) {
printf ( " error\n " );
return 1 ;
}
while ( - 1 != fscanf (fp, " %s " , str)) {
sprintf (command, " ar -r %s %s " , mainlib, str);
// sprintf (command, " ar -d %s %s " , mainlib, str);
// printf ( " %s\n " , command);
system (command);
sprintf (command, " del %s " , str);
system (command);
}
fclose (fp);
return 0;
}