静态库与动态库原理,编译流程详解。
编译原理和语法详解(何老师)
编译流程(高级语言转换成二进制机器语言)
主要流程有:
预处理:完成宏替换,以及去除空行,注释等,为下一步的编译做准备。也就是对各种预处理进行处理,包括头文件的包含、宏定义的扩展、条件编译的选择等。
gcc -E test.c -o test.i 其中的E表示gcc在进行预处理后不再进行下面的操作了。
编译:将预处理后的代码编译成汇编代码。在这个阶段中首先要检查代码的规范性、是否有语法的错误等。以确定代码实际要做的工作,在检查无误后,再把代码翻译成汇编语言。
编译程序执行时,先分析,后综合,分析,就是指词法分析,语法分析,语义分析和中间代码生成。综合,就是指代码优化和代码生成。
大多数的编译程序直接产生机器语言的目标代码,形成可执行的目标文件,也有的是先产生汇编语言一级的符号代码文件再调用汇编程序进行翻译和加工处理,最后产生可执行的机器语言目标文件。
gcc -S test.i -o test.s 其中的S让gcc在编译结束后停止编译过程,“test.s”文件为编译后生成的汇编代码。
汇编:就是把编译阶段生成的".s"文件转成二进制目标代码,也就是机器代码(01序列)
gcc -c test.s -o test.o -C表示gcc在汇编结束后停止编译过程,test.o文件为汇编生成的机器码目标文件。
链接:就是将多个目标文件以及所需的库文件链接生成可执行目标文件的过程。
gcc test.o -o test test可执行文件,-o本质上是一个重命名选项,不使用-o选项时默认生成的时a.out文件。
静态库
静态库实际就是一些目标文件(一般以.o结尾)的集合,静态库一般以.a结尾,只用于生成可执行文件阶段。
在链接步骤中,链接器将从库文件取得所需代码,复制到生成可执行文件中。这种库称为静态库。其特点是可执行文件中包含了库文件的一份完整拷贝,在编译的过程中被载入程序中,缺点是多次使用就会有多份赘余拷贝,并对程序的更新部署和发布回带来麻烦,如静态库有更新,那么所有使用它的程序都要重新编译,发布。
生成静态库,首先生成test.o目标文件,使用ar命令将test.o打包成libtest.a静态库
动态库
动态库在链接阶段没有被复制到程序中,而是在程序运行时由系统动态加载到内存中供程序调用。
系统只需载入一次动态库,不同的程序可以得到内存中相同动态库的副本,因此节省很多内存,
生成静态库:
生成动态库
动态库和静态库的区别
MakeFile走读与语法基础
makeFile是什么 是make脚本工具
定义一系列规则,自动化编译脚本
makefile包含五个:
显示规则:说明如何生成或多个目标文件
隐晦规则:makefile有自动推导
变量定义:makefile可以定义很多变量,变量就是字符串
文件指示:1、一个引用另一个,2、指定makefile有效部分 ,3、定义多行命令
注释 行注释,用#注释
Makefile的规则
target:目标文件,可以是ObjectFile,也可以是执行文件,还可以是标签(Lable)
prerequisites:依赖文件,即要生成的那个target所需要的文件或其他target
command :make需要执行的命令
如果在同一行的可以用分号,如果不在一行比如使用tab键
Makefile事例
Makefile是如何工作的
Makefile中使用变量
引用其他的Makefile
环境变量MAKEFILES
Makefile预定义变量
Makefile自动变量
Makefile的函数
make的工作流程
GNU的make工作时的执行步骤如下:
-
读入所有的Makefile。
-
读入被include的其他Makefile
-
初始化文件中的变量
-
推导隐晦规则,并分析所有规则
-
为所有的目标文件创建依赖关系链
-
根据依赖关系,决定那些目标要重新生成
-
执行生成命令
Android.mk基础
Android.mk是一个向Android NDK构建系统描述NDK项目的GNUmakefile片段。主要用来编译生成以下几种:
-
APK程序:一般的Android应用程序,系统级别的直接push即可
-
JAVA库:JAVA类库,编译打包生成JAR文件
-
C\C++应用程序:可执行的c\c++应用程序
-
C\C++静态库:编译生成C\C++静态库,并打包成.a文件
-
C\C++共享库:编译生成共享库,并打包成so文件。
Android.mk基本格式
编译多个共享库
编译静态库
使用共享库共享通用模块
如何使用预编译库
编译独立的可执行文件
注意