开放、自由和灵活是Linux 的美丽所在,GCC 可以更具自己的调试需求制作出相应的修改。
Gcc
基础知识
介绍
GCC(GNU Compile Collection),GNU发布的
硬件平台:x86(大端)、Arm(大小端都支持,需要指定)/Mips(小端)等不同体系结构的硬件平台
支持语言:c 、C++、Java等等十种
总体选项:
控制整体流程,选项如下:
-c: 源文件进行编译或者汇编
-E: 源文件预编译 Exem:gcc -E test.c -o test.i
-S: 源文件进行编译 Exem:gcc -S test.c -o test.s
-o file: 目标文件file
-v: 显示编译阶段的命令
语言选项:
用于支持各种版本的C语言程序
-ansi: 支持符合ANSI 标准的C 程序
告警选项:
控制在编译过程中的各种告警信息的显示,
有30多条告警信息,有3个告警级别,有助于程序的稳定性和可移植性
-W: 屏蔽所有的告警信息
-Wall: 显示所有类型的告警信息
-Werror: 出现任何告警信息就停止编译
调试选项
-g: 产生调试信息添加到可执行文件中
优化选项
-O1: 对目标文件的性能进行优化
-O2: 在O1 的基础上进一步优化,提高目标文件的运行性能
-O3: 在O2的基础上进一步优化,支持函数的集成优化
-O0: 不进行优化处理
连接器选项
-static: 使用静态链接
-llibrary: 链接library 函数库文件
-L dir: 指定连接器的搜索目录 dir
-shared: 生成共享文件 动态
-Idir :指定头文件的搜索路径
-Ldir :指定搜索目录dir
编译提效
-m :并行编译,平摊到各个数据核上,需要注意在并行编译时,相互依赖关系的处理
流程介绍:
GCC 命令生成的可执行文件有三种格式:
a.out
Coff:较老的格式
Elf:linux 平台可执行文件的主流格式
预编译:
gcc -E test.c -o test.i
编译的时候首先会把头文件的内容加载到test.c 中
编译:
Gcc -S test.i -o test.s(汇编)
词法分析:关键字,标识符的检查
语法分析:语法的检查
语义分析:逻辑意义的检查
汇编:
gcc -c test.i -o test.o(目标文件)
链接:
需要把test.o 和 函数库文件链接一起才能生成可以直接运行的文件
库的使用:
动态链接库:在运行阶段有需要才会链接相关的库文件。可执行文件的体积较大,运行效率较高。动态链接的时候会把相关的链接文件写入到二进制文件中,这样在运行的时候就可以通过符号链接文件找到指定的动态库文件了。
静态链接库:链接阶段就已经把目标文件和库文件链接到一起了。体积较小,运行效率较低。
Glibc 是C语言的函数库,符合ISO C 和 POSIX标准,ISO C 定义的C函数库的标准格的POSIX 定义的不通计算机应该遵守的C函数库标准,是ISO C 的补充。
Glibc包含的库包括:数学库libm ,加密库 libcrypt、线程库 libpthread、网络服务库 libnsl以及输入、输出函数、字符串处理、数学函数、中断处理函数、错误处理函数、日期计算函数等等。
头文件都存放在/usr/include目录中,使用-I 链接 libm 为m、libpthread 为pthread。
库文件存放在 /usr/lib和/lib中
使用file 查看动态链接库的链接情况,使用objdump 和readelf 两个命令,我们可以看到elf的各个节段的 信息还有 运行时需要那些动态链接库,elf中的汇编代码等等(具体信息自己查看)
调试器:gdb
查看源文件:list 查看代码行号
设置短点:b
查看断点情况: info b
运行程序: r/c
单步运行:s
程序环境设置:
使用shell 命令:(gdb) shell 命令行:执行shell命令行
查看变量的数值:p\x
工程管理makefile
优点:管理方便,调试效率高
组成:
目标文件(target fie)
依赖文件(dependency file)
编译规则(command---tab键)
依赖规则是Make工程管理器的核心工作。
工作流程:
1. 读取当前目录下的makefile 文件
2. 查找makefile 中的第一个目标,也是工程中的最终目标
3. 那目标文件的依赖文件当做进行依赖规则检查
A. 如果当前目录没有目标文件,则执行其规则命令生成目标文件;
B. 如果存在目标文件,则检查目标文件与依赖文件的时间,按照规则更新目标文件;
C. 如果目标文件比依赖文件新,则不做处理;
4. 递归执行第三部
Makefile 特性:
变量:
使用字符、数字、下划线、大小写敏感
Obj :目标文件
赋值:
= 来实现变量赋值
:=
+=
?=
自动推导
obj= a.o b.o .PHONY:all all:test $(obj) cc -o test $(obj) .PHONY:clean clean:test $(obj) rm -rf test $(obj) |
伪目标.PHONY:
通过伪目标可以让项目只执行规则命令
All: make all
Clean:make clean
文件查找
VPATH:特殊变量,若是在当前路径找不到文件,那就会到VPATH 中执行的路径中查找
VPATH= /a : /b 按照顺序查找
vpath : 关键字
VPATH = /home/b Obj=a.o b.o .PHONY:all all:test $(obj) cc -o test $(obj) | vpath %.c /home/b Obj=a.o b.o .PHONY:all all:test $(obj) cc -o test $(obj) |
嵌套执行
VPATH = /home/b Obj=a.o b.o .PHONY:all all:test $(obj) cc -o test $(obj) b.o:b.c---------嵌套 cd b && make |
条件判断
1. ifeq ...else...
2. ifneq ...else...
3. ifdef ...else...
4. ifndef ...else...
函数
常用的基础函数:
1.error
$(error ==========)
result := $(error error occure!)
2.warning
$(warning =============)
result := $(warning warning occure!)
3.if 判定条件
ifeq ($(TARGET_ARCH), arm) LOCAL_SRC_FILES := ... else ifeq ($(TARGET_ARCH), x86) LOCAL_SRC_FILES := ... else ifeq ($(TARGET_ARCH), mips) LOCAL_SRC_FILES := ... else LOCAL_SRC_FILES := ... endif |
4.call
reverse=$(2) $(1) foo=$(call reverse, a, b) all: @echo $(foo) |
b a 结束 |
5.foreach
a:= x y z result := $(foreach b,$(a),$(b).c) |
result是 x.c y.c z.c |
6.Addprefix
$(addprefix src/,foo bar) 返回值为“src/foo src/bar” |
7.Addsubfix
$(addprefix .src,foo bar) 返回值为“foo.src bar.src” |
8.Filter
$(filter pattern...,text) 返回在text中由空格隔开且匹配pattern...的字,并将不符合pattern...的字移出。 |
9.Findstring
$(findstring string,text) 在text中搜寻string,如果找到返回值是string,否则返回值为空。 |
10.Strip
$(strip text) 去掉前导和结尾空格,并将字中间的多个空格压缩为单个空格。 |
11.Wildtrip
$(strip text) 去掉前导和结尾空格,并将字中间的多个空格压缩为单个空格。 |
12.Dir
$(dir names...) 抽取每一个文件名的路径部分,文件名的路径部分包括从文件名的开始到最后一个斜杠(含斜杠)之前的一切字符。如果文件名中没有斜杠,路径部分是“./”。 |