Linux平台gcc和动态共享库的基础知识
对大多数不从事Linux平台C语言开发的人来说,GNU gcc的一套工具和Linux平台的共享库的使用还是十分陌生的,其实我也不太熟悉,姑且写点基础知识,权当做备忘吧。一、GNU gcc的编译工具用法
我们先来写一个简单的C程序:hello.c
#include <stdio.h>void print_hello() {printf("Hello World\n");}int main(int argc, char argv[]) {print_hello();return 0;}
定义了一个print_hello函数,调用main函数打印Hello World。
如何编译它呢?
gcc -o hello -O2 hello.c
-o参数指定生成的可执行程序的文件名, -O2是优化级别。该命令会编译生成hello可执行程序,看看这个文件:ls -l hello
-rwxr-xr-x1 robbin users 11939 2008-11-02 13:48 hello
有11KB大小。
看看他链接了哪些系统动态链接库,用ldd命令:
ldd hello
输出信息为:
libc.so.6 => /lib64/tls/libc.so.6 (0x0000002a9566d000)/lib64/ld-linux-x86-64.so.2 (0x0000002a95556000)
libc是C语言标准函数库,ld是动态链接器。
接着我们看看hello这个程序里面有哪些符号,用nm命令:
nm hello
输出:
00000000005008f8 A __bss_start000000000040043c t call_gmon_start......00000000004004f0 T main0000000000500658 d p.000000000004004e0 T print_hello U puts@@GLIBC_2.2.50000000000400410 T _start
中间省略了一些,不过我们还是可以在符号表里面找到函数定义。
hello有11KB,体积偏大,去处符号表可以给它瘦身,我们用strip命令:
strip hello
然后再ls -l hello,输出为:
-rwxr-xr-x1 webuser users 4464 2008-11-02 13:56 hello
只有4.4KB了,瘦身效果明显! 不过这次符号表再也看不到了,nm hello,输出为:nm: hello: no symbols。
最后如果我们想从可执行程序里面提取出来一点什么文本信息的话,还可以用strings命令:
strings hello
输出信息为:
/lib64/ld-linux-x86-64.so.2SuSElibc.so.6puts__libc_start_main__gmon_start__GLIBC_2.2.5t fffHello World
友情提醒一下,如果你用Java写一个HelloWorld.java,编译以后你也可以用strings窥探一番。
二、动态共享库怎么使用
这次我们把hello.c拆开成为两个文件:hello.c和main.c。hello.c的代码是:
#include <stdio.h>void print_hello() {printf("Hello World\n");}
而main.c的代码是:
int main(int argc, char argv[]) {print_hello();return 0;}
hello.c是我们的动态共享库,在hello.c里面我们声明和实现了各种公用的函数,最后main.c可以去调用这些公用函数。首先我们要把hello.c编译成为动态共享库:
gcc -o libhello.so -O2 -fPIC -shared hello.c
-fPIC参数声明链接库的代码段是可以共享的,-shared参数声明编译为共享库。请注意这次我们编译的共享库的名字叫做libhello.so,这也是Linux共享库的一个命名的惯例了:后缀使用so,而名称使用libxxxx格式。
然后编译main.c的时候,我们需要更多的参数让gcc知道如何寻找共享库:
gcc -o main -O2 -L. -lhello main.c
-L参数指定到哪个附加路径下面去寻找共享库,现在我们指定在当前目录下面寻找;
-l参数指定链接到哪个共享库上面,我们传的参数hello,那么gcc就会自动链接到libhello.so这个共享库上面(注意我们上面说的libXXXX.so命名规则);
-I参数指定到哪个附加路径下面去寻找h文件,这个我们没有使用。
最后我们成功编译好了main,执行一下,报错:
<div class="quote_title">引用
页:
[1]