linux下制作发布自己的静态库
目录
1、linux的库library介绍
2、库程序的编译使用
3、例子libtest库
4、小结
1、linux的库library介绍
编写程序,已经不再是起步时候的一个xx.c程序了,
尤其在大的项目当中,那几乎不可思议的
我们可以把不同程序写在不同.c里面,首先编译成.obj文件,
最后链接生成程序的时候,包含进去所有的.obj
比如objtest.c包含了某些功能函数,objtest.h对这些函数进行了声明
我们的main.c源码里面,只需要包含objtest.h,
然后在程序里面使用objtest.c的函数
编译这个工程的时候,首先编译出.obj文件
然后编译主程序的时候,只要链接进去这个objtest.o,即可
如果我们的另一个项目也需要这些功能的函数,
必须拷贝相同的一份源码过去,编译成.obj,
然后供这个新的工程生成链接时候使用
能否有更好的办法?!
嘿嘿,在使用linux的时候,
大家编译源码的时候,肯定见过一些lib文件
某些程序编译的时候需要一些lib支持,而一个lib可以支持多处程序编译,
我们只要把功能函数编译成lib存储起来,就一样可以到处用了
在linux下有静态库(static library,.a文件)和共享库(shared library,.so文件)之分,
就像win32系统中,存在静态库(.lib)和动态库(.dll)一样
静态库和共享库都是一个obj文件的集合,
但静态链接后,执行程序中存在自己所需obj的一份拷贝,
而动态链接后,执行程序仅仅是包含对共享库的一个引用。
共享库相当于一个由多个obj文件组合而成的obj文件,在链接后其所有代码被加载,不管需要的还是不需要的。
似乎可以得出一个结论:
静态链接后的程序比动态链接的所用存储空间大,因为执行程序中包含了库中代码拷贝;
而动态链接的程序比静态链接的所用的运行空间大,因为它将不需要的代码也加载到运行空间。
(ps:引用概念)
动态链接库虽然可以类似插件给编译好了的二进制程序实现不能功能及升级,
但是想在运行时动态加载、卸载库时,需要用到一些dl库函数:dlopen、dlclose、dlsym等等
并且程序发布的时候,需要随身携带那些.so文件
而静态库是一劳永逸,编译后不需要带一堆库文件跑,而且不管放置到哪里都可正常运行。
再次我们就不讲解它了,感兴趣的朋友可以参见此篇文章
http://groups.google.com/group/d ... F%E8%AE%BE%E8%AE%A1
2、库程序的编译使用
静态库的编译,实际上是一个将.o文件打包的过程
我们编译程序就跟标准库函数调用一模一样了
首先解压缩libtest.tar.gz
头文件libtest.h
现在我们来编译这个静态链接库
只要程序中包含libtest.h,编译时候带-ltest参数,
都可以调用静态链接库中的test_add和test_sub功能函数,
并且代码会被编译到生成的程序里面,程序可以在没有安装libtest的系统中可以正常运行
我们看看包里面自带的一个演示例子
4、小结
虽然系统有许多函数库调用了,但是有些操作起来比较复杂,
比如mysql,首先声明一个mysql的指针,然后初始化,然后连接服务器,
然后执行SQL语句,然后获取返回...然后关闭mysql断开连接...
我们可以通过上述方式,封装我们自己的一些库,比如libdmysql
一个d_mysql_query函数就可以执行一句SQL
再把这些封装起来了的库,添加到系统中,方便开发,还不误程序的使用(静态库嘛)
也可以编写自己的一些函数库,发布共享,一起提高技术,支持开源:)
目录
1、linux的库library介绍
2、库程序的编译使用
3、例子libtest库
4、小结
1、linux的库library介绍
编写程序,已经不再是起步时候的一个xx.c程序了,
尤其在大的项目当中,那几乎不可思议的
我们可以把不同程序写在不同.c里面,首先编译成.obj文件,
最后链接生成程序的时候,包含进去所有的.obj
比如objtest.c包含了某些功能函数,objtest.h对这些函数进行了声明
我们的main.c源码里面,只需要包含objtest.h,
然后在程序里面使用objtest.c的函数
编译这个工程的时候,首先编译出.obj文件
QUOTE:
gcc -c objtest.c
目录下就生成了objtest.o,
然后编译主程序的时候,只要链接进去这个objtest.o,即可
QUOTE:
gcc -o test main.c objtest.o
但是.obj有个不好的地方,就是一份.obj只能给一个工程使用
如果我们的另一个项目也需要这些功能的函数,
必须拷贝相同的一份源码过去,编译成.obj,
然后供这个新的工程生成链接时候使用
能否有更好的办法?!
嘿嘿,在使用linux的时候,
大家编译源码的时候,肯定见过一些lib文件
某些程序编译的时候需要一些lib支持,而一个lib可以支持多处程序编译,
我们只要把功能函数编译成lib存储起来,就一样可以到处用了
在linux下有静态库(static library,.a文件)和共享库(shared library,.so文件)之分,
就像win32系统中,存在静态库(.lib)和动态库(.dll)一样
静态库和共享库都是一个obj文件的集合,
但静态链接后,执行程序中存在自己所需obj的一份拷贝,
而动态链接后,执行程序仅仅是包含对共享库的一个引用。
共享库相当于一个由多个obj文件组合而成的obj文件,在链接后其所有代码被加载,不管需要的还是不需要的。
似乎可以得出一个结论:
静态链接后的程序比动态链接的所用存储空间大,因为执行程序中包含了库中代码拷贝;
而动态链接的程序比静态链接的所用的运行空间大,因为它将不需要的代码也加载到运行空间。
(ps:引用概念)
动态链接库虽然可以类似插件给编译好了的二进制程序实现不能功能及升级,
但是想在运行时动态加载、卸载库时,需要用到一些dl库函数:dlopen、dlclose、dlsym等等
并且程序发布的时候,需要随身携带那些.so文件
而静态库是一劳永逸,编译后不需要带一堆库文件跑,而且不管放置到哪里都可正常运行。
再次我们就不讲解它了,感兴趣的朋友可以参见此篇文章
http://groups.google.com/group/d ... F%E8%AE%BE%E8%AE%A1
2、库程序的编译使用
静态库的编译,实际上是一个将.o文件打包的过程
QUOTE:
ar -rc libtest.a libtest1.o libtest2.o
静态库的调用比较简单,跟标准库函数调用一样
QUOTE:
gcc -o test main.c -I头文件的路径 -L库文件的路进 -ltest
如果把头文件和库文件复制到gcc默认的头文件目录/usr/include和/usr/lib里面
我们编译程序就跟标准库函数调用一模一样了
QUOTE:
gcc -o test main.c -ltest
3、例子libtest库
首先解压缩libtest.tar.gz
QUOTE:
dorainm@thinkpad:~/workroom/lib$ tar xzvf libtest.tar.gz
libtest/
libtest/src/
libtest/src/libtest1.c
libtest/src/libtest2.c
libtest/src/libtest.h
libtest/src/Makefile
libtest/src/libtest1.o
libtest/src/libtest2.o
libtest/src/libtest.a
libtest/example/
libtest/example/main.c
libtest/example/Makefile
libtest/Makefile
libtest/AUTHOR
libtest/README
libtest/INSTALL
dorainm@thinkpad:~/workroom/lib$
查看源码
libtest/
libtest/src/
libtest/src/libtest1.c
libtest/src/libtest2.c
libtest/src/libtest.h
libtest/src/Makefile
libtest/src/libtest1.o
libtest/src/libtest2.o
libtest/src/libtest.a
libtest/example/
libtest/example/main.c
libtest/example/Makefile
libtest/Makefile
libtest/AUTHOR
libtest/README
libtest/INSTALL
dorainm@thinkpad:~/workroom/lib$
头文件libtest.h
QUOTE:
dorainm@thinkpad:~/workroom/lib$ cd libtest/src
dorainm@thinkpad:~/workroom/lib/libtest/src$ more libtest.h
#ifndef __LIBTEST_H__
#define __LIBTEST_H__
extern int test_add( int a );
extern int test_sub( int a );
#endif
dorainm@thinkpad:~/workroom/lib/libtest/src$
功能函数1源码libtest1.c
dorainm@thinkpad:~/workroom/lib/libtest/src$ more libtest.h
#ifndef __LIBTEST_H__
#define __LIBTEST_H__
extern int test_add( int a );
extern int test_sub( int a );
#endif
dorainm@thinkpad:~/workroom/lib/libtest/src$
QUOTE:
dorainm@thinkpad:~/workroom/lib/libtest/src$ more libtest1.c
#include <stdio.h>
#include "libtest.h"
extern int test_add( int a )
{
return (a+1);
};
dorainm@thinkpad:~/workroom/lib/libtest/src$
#include <stdio.h>
#include "libtest.h"
extern int test_add( int a )
{
return (a+1);
};
dorainm@thinkpad:~/workroom/lib/libtest/src$
QUOTE:
功能函数2源码libtest2.c
dorainm@thinkpad:~/workroom/lib/libtest/src$ more libtest2.c
#include <stdio.h>
#include "libtest.h"
extern int test_sub( int a )
{
return (a-1);
};
dorainm@thinkpad:~/workroom/lib/libtest/src$
我们可以看到,libtest函数提供2个函数,test_add和test_sub
dorainm@thinkpad:~/workroom/lib/libtest/src$ more libtest2.c
#include <stdio.h>
#include "libtest.h"
extern int test_sub( int a )
{
return (a-1);
};
dorainm@thinkpad:~/workroom/lib/libtest/src$
现在我们来编译这个静态链接库
QUOTE:
dorainm@thinkpad:~/workroom/lib/libtest/src$ make
gcc -Wall -o libtest1.o -c libtest1.c
gcc -Wall -o libtest2.o -c libtest2.c
ar -rc libtest.a libtest1.o libtest2.o
dorainm@thinkpad:~/workroom/lib/libtest/src$
然后安装
gcc -Wall -o libtest1.o -c libtest1.c
gcc -Wall -o libtest2.o -c libtest2.c
ar -rc libtest.a libtest1.o libtest2.o
dorainm@thinkpad:~/workroom/lib/libtest/src$
QUOTE:
dorainm@thinkpad:~/workroom/lib/libtest/src$ sudo make install
install libtest.a -m 644 /usr/lib/
install libtest.h -m 644 /usr/include/
dorainm@thinkpad:~/workroom/lib/libtest/src$
好了,现在我们任何一个程序源码,
install libtest.a -m 644 /usr/lib/
install libtest.h -m 644 /usr/include/
dorainm@thinkpad:~/workroom/lib/libtest/src$
只要程序中包含libtest.h,编译时候带-ltest参数,
都可以调用静态链接库中的test_add和test_sub功能函数,
并且代码会被编译到生成的程序里面,程序可以在没有安装libtest的系统中可以正常运行
我们看看包里面自带的一个演示例子
QUOTE:
dorainm@thinkpad:~/workroom/lib/libtest/src$ cd ../example/
dorainm@thinkpad:~/workroom/lib/libtest/example$ more main.c
#include <stdio.h>
#include <libtest.h>
int main( void )
{
int a = 7;
printf( "%d => %d/n", a, test_add(a) );
printf( "%d => %d/n", a, test_sub(a) );
return 0;
};
dorainm@thinkpad:~/workroom/lib/libtest/example$
我们来编译这个程序
dorainm@thinkpad:~/workroom/lib/libtest/example$ more main.c
#include <stdio.h>
#include <libtest.h>
int main( void )
{
int a = 7;
printf( "%d => %d/n", a, test_add(a) );
printf( "%d => %d/n", a, test_sub(a) );
return 0;
};
dorainm@thinkpad:~/workroom/lib/libtest/example$
QUOTE:
dorainm@thinkpad:~/workroom/lib/libtest/example$ make
gcc -Wall -o libtest-example main.c -ltest
dorainm@thinkpad:~/workroom/lib/libtest/example$ ls
libtest-example main.c Makefile
dorainm@thinkpad:~/workroom/lib/libtest/example$
可以看到目标程序被编译成功,现在运行程序看看
gcc -Wall -o libtest-example main.c -ltest
dorainm@thinkpad:~/workroom/lib/libtest/example$ ls
libtest-example main.c Makefile
dorainm@thinkpad:~/workroom/lib/libtest/example$
QUOTE:
dorainm@thinkpad:~/workroom/lib/libtest/example$ ./libtest-example
7 => 8
7 => 6
dorainm@thinkpad:~/workroom/lib/libtest/example$
okay,libtest库里面的2个功能函数被正常调用
7 => 8
7 => 6
dorainm@thinkpad:~/workroom/lib/libtest/example$
4、小结
虽然系统有许多函数库调用了,但是有些操作起来比较复杂,
比如mysql,首先声明一个mysql的指针,然后初始化,然后连接服务器,
然后执行SQL语句,然后获取返回...然后关闭mysql断开连接...
我们可以通过上述方式,封装我们自己的一些库,比如libdmysql
一个d_mysql_query函数就可以执行一句SQL
再把这些封装起来了的库,添加到系统中,方便开发,还不误程序的使用(静态库嘛)
也可以编写自己的一些函数库,发布共享,一起提高技术,支持开源:)