JNI基础--编译流程、静态库与动态库

2020-04-21  本文已影响0人  刘小厨
编译流程

编译分为四大步骤:

预处理

●完成宏替换、文件引入,以及去除空行、注释等,为下一步的编译做准备。
●也就是对各种预处理命令进行处理,包括头文件的包含、宏定义的扩展、条件编译的选择等。

指令:

# test.c文件内容
#include <stdio.h>
int main( ) {
printf("hello world!\n") ;
return 0;
--------------------------------
$ gcc -E test.c -o test.i

其中选项-E表示让gcc在预处理结束后停止编译等后续操作,“test.i”文件为预处理后输出的文件。
-o:指定输出文件。

处理前后

我们可以看到处理之后的文件的体积会变大很多,而且“test.i”为文本文件,可以用文本编辑器打开

编译

gcc命令(对预编译后的文件执行编译指令):

$ gcc -S test.i -o test.s

选项-S让gcc在编译结束后停止编译过程,“test.s”文件为编译后生成的汇编代码。

汇编

gcc命令(对编译后的文件执行汇编指令):

$ gcc -C test.s -o test.o

选项-c让gcc在汇编结束后停止编译过程,“test.o”文件为汇编后生成的机器码目标文件。

链接

gcc命令:

$ gcc test.o -o test

-o本质上是一个重命名选项。不使用-o选项时,默认生成的是a.out文件。这里生成的是可执行文件test
./test执行后输出"helloworld!"

或者我们可以这一步到位,用gcc命令直接将.c文件生成一个可执行文件
gcc命令:

gcc -o test test.c
静态库与动态库

了解了编译流程之后,我们看下静态库和动态库

静态库

静态库概念:

生成静态库的gcc命令:

#首先生成目标文件(如果需要,生成多个目标文件)
//$ gcc -C test.c与下面一行代码等效,会生成一个同名.o文件,也就是test.o
$ gcc -C test.c -o test.o
#使用ar命令将目标文件打包成静态库 选项rcs分别表示
#r表示更新或增加新文件
#c表示创建一个库,不管存在与否
#s表示创建文档索引
$ar rcs libtest.a test.o
//ar: creating libtest.a
#使用ar t libtest.a 查看静态库内容
$ ar t libtest. a
test.o

动态库:

生成动态库的gcc命令:

#首先生成目标文件(如果需要,生成多个目标文件)
//$ gcc -C test.c与下面一行代码等效,会生成一个同名.o文件,也就是test.o
$ gcc -C test.c -o test.o
#使用- fPIC和- shared生成动态库
$ gcc -shared -fPIC -o libtest.so test.o 

其中fPIC表示:用于生成位置无关的代码(Position-Independent-Code),以供生成动态库使用

注:生成静态库或动态库后,可通过gcc命令编译生成可执行文件:

//生成静/动态库后
//编译可执行文件,并且链接静态库,
//-l表示指定要链接的库后面跟的是库的名字(这里是:tool),
//-L表示编译程序暗转-L后面指定的路径去寻找库文件 . 表示当前文件夹
//$gcc -o main main.c  -L. -ltool

使用上述命令需要注意:

image.png

动态库与静态库的区别:

载入时刻不同:
● 静态库在程序编译时会链接到目标代码中,程序运行时不再需要静态库,因此体积较大。而且每次编译都需要载入静态代码,因此内存开销大。

● 动态库在程序编译时不会被链接到目标代码中,而是在程序运行时才被载入,程序运行时需要动态库存在,因此体积较小。而且系统只需载入一次动态库,不同程序可以得到内存中相同的动态库副本,因此内存开销小。

上一篇下一篇

猜你喜欢

热点阅读