(一)GCC Makefile熟悉

xiaoxiao2021-02-28  76

一、GCC编译器

1、概念:

全称为GNU CC ,GNU项目中符合ANSI C标准的编译系统

  GNU  C and C++ compiler

  GNU compiler collection

2、特点:

1》可编译C、C++、Object C、Java、Fortran、Pascal、Modula-3和Ada等多种语言

2》GCC是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%

3》同时是交叉平台编译器 ,适合在嵌入式领域的开发编译

3、gcc如何编译程序:

1》单文件程序:

2》多文件程序:

4、预处理: 1》去掉源程序中的注释 2》文件包含:包含的是头文件(.h) 将头文件中的内容复制到当前文件中 1)头文件在系统目录中(系统头文件) #include <头文件名.h> 直接去系统的头文件目录下寻找该头文件 2)头文件在当前目录中(自己写的头文件) #include "头文件名.h" 先在当前目录下寻找,找不到则去系统的头文件目录下寻找该头文件 3)头文件的内容: ----》包含其他头文件 ----》定义全局变量 ----》声明变量 ----》声明函数 ----》定义宏 ----》写条件编译语句 ----》内联函数 ----》定义复杂的数据类型 4)头文件的作用: 在C语言中,主要是用于被.C的源文件包含,所以在编译语句中不会出现。 3》宏替换: 1)预定义宏: __FILE__ 正在编译的文件名 __LINE__ 文件当前的行号 __func__ 当前所在的函数名 __DATE__ 预编译文件的日期 __TIME__ 预编译文件的时间 __STDC__ 判断编译器是否遵循ANSI C,是则为1 其中, __LINE__和__STDC__是整型常量,其余为字符串常量。 2)不带参数宏: #define PI 3.14 #define SIZE 64 3)带参数宏:

#define MAX(a, b) (a) > (b) ? (a): (b)

#define FUN1(a, b) (a) * (b) + 3

4》条件编译: 1)第一种: #ifdef 宏 代码块A; #else 代码块B; #endif 如果宏被定义,则编译代码块A;否则,编译代码块B; 一般用于测试代码块中,例如:

#include <stdio.h> #define DEBUG int fun(int a,int b) { //...... return a + b; } #ifdef DEBUG int main(void) { printf("%d\n",fun(3,5)); } #endif 2)第二种: #ifndef 宏 代码块A; #else 代码块B; #endif 如果宏没有被定义,则编译代码块A;否则,编译代码块B; 一般用于头文件中,作用是:防止当前头文件被多次(重复)包含,例如:

#ifndef __HEAD_H__ #define __HEAD_H__ #include <stdio.h> int xy = 100; #endif 3)第三种: #if 表达式(bool值) 代码块A; #else 代码块B; #endif 如果表达式为真,则编译代码块A;否则,编译代码块B;

一般用于注:

5、链接: 1》符号解析 解析每个.o文件中的符号有没有被定义,如果没有定义,则报错,如果有定义,则解析成功 2》重定位 将每个.o文件中对应段中的数据和代码,在可执行文件的对应段中重新分配地址。

二、GDB调试器 1、调试的目的: 当程序在运行过程中出现一些问题时,需要使用调试器进行调试 2、调试的方法: 通过在程序中设置断点,观察程序每一步运行的状态,分析与实际的结果的差别,找出问题,解决问题 3、调试的工具: GDB调试器 4、GDB的使用: GDB是命令行的调试器,所有的操作都是通过命令完成。 1》调试的条件: 编译时,需要加"-g"选项 2》调试的对象: 编译之后生成的可执行的程序 3》如何进入GDB调试器: $ gdb 调试对象 4》GDB相关命令: 1)退出调试器: quit 2)查看代码: l l 默认显示10行代码 l   n 显示以n为中间行的10行代码 l   n,m 显示从第n行到第m行的代码 3)设置断点:b b  n n为行号 4)删除断点:d d n n为断点编号 5)查看断点信息:info  info   b 6)在gdb中运行程序:r 7)查看变量信息:p p   变量名 8)单步运行:n,s ----》n:当遇到函数调用语句时,直接调用函数,停在函数调用语句的下一条语句,前提是该函数中没有断点 ----》s:当遇到函数调用语句时,将进入被调用函数,然后单步执行 9)继续执行:continue

三、工程管理器:make 1、概念: make:自动编译管理器,能够根据程序中每一个源文件的更新时间自动编译文件,从而提高编译的效率。 make必须通过读取Makefile文件中的内容来执行编译工作。 2、Makefile 是make的脚本文件,Makefile文件中写了make执行的流程,所以make的执行通过Makefile文件控制。 故:通过写Makefile文件可以控制make编译程序。 3、Makefile怎么写? Makefile文件是由许多规则组成,这里的规则就类似于c语言中函数,具有一定的格式,格式如下:

目标体: 依赖文件列表

《Tab键》 命令(shell命令、编译的命令)

实例1

7_test:7_test.c

    gcc -o 7_test 7_test.c

实例2

4、make如何读取Makefile文件内容?

5、Makefile中的变量: 1》Makefile中,所有变量的值都是字符串,该字符串可以表示一下这些内容: 文件的名字  给编译器的参数  需要运行的程序  需要查找源代码的目录  需要输出信息的目录 你想做的其他事情 2》分类 1)自定义变量: ---》递归展开定义

当引用变量时,如果变量在前面没有定义,可以向下寻找该变量的定义,并将值展开

---》简单定义

2)预定义变量 在make中预先定义好的变量,如果有默认值,可以直接使用,如果没有默认值,则需要赋值后使用 CC C编译器的名称,默认值为cc。CPP  C预编译器的名称,默认值为$(CC) –E。 RM 文件删除程序的名称,默认值为rm -f CFLAGS   C编译器的选项,无默认值。 实例3:

3)自动变量: $*   不包含扩展名的目标文件名称 $+   所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件 $<    第一个依赖文件的名称 $?    所有时间戳比目标文件晚的的依赖文件,并以空格分开   $@    目标文件的完整名称 $^     所有不重复的目标依赖文件,以空格分开 $%      如果目标是归档成员,则该变量表示目标的归档成员名称 自动变量用在规则里的命令中,表示该规则中的目标体或者依赖文件。 实例:

6、模式规则:模板 也叫模板规则,可以自动生成许多相似的规则,通过用%替代具体的文件名,例如:

7、Makefile中的函数:

转载请注明原文地址: https://www.6miu.com/read-66849.html

最新回复(0)