GCC、GDB及Makefile的相关使用

前言

本文总结了基本的Linux下GCC编译器,GDB调试器及Makefile的使用方法。


目录

 一、GCC

1.GCC的介绍

2.GCC的使用

二、GDB

1.GDB的介绍

2.GDB的使用

三、Makefile

1.基本概念

2.使用方法


一、GCC

1.GCC的介绍

        GCC(GNU Compiler Collection,GNU 编译器套装)是一套由 GNU 开发的编程语言编译器。GCC 是非常优秀的跨平台编译器集合,支持 x86、ARM、MIPS 和 PowerPC 等多种目标平台。GCC 原名为 GNU C 语言编译器(GNU C Compiler),因为它原本只能处理 C 语言。GCC 很快地扩展,变得可处理 C++。之后也变得可处理 Fortran、Pascal、Objective-C、Java,以及 Ada 与其他语言。

2.GCC的使用

(1).GCC指令的一般格式

gcc [选项] 要编译的文件列表  [-o 目标文件]
//目标文件可缺省,gcc默认生成可执行的文件为a.out

//单文件编译
gcc test.c
//多文件编译
gcc main.c add.c -o main

(2).GCC的选项

        gcc有超过100个的可用选项,主要包括总体选项、告警和出错选项、优化选项和体系结构相关选项。下表为常用选项。

lifthong

(3).GCC常见的后缀名及其含义

(4).gcc的执行过程

        虽然称gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤:预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking),如图所示。

a.预处理(preprocess)

        这个阶段主要处理源文件中的 #ifdef、#include和 #define命令。对于该阶段,gcc将stdio.h文件中的代码包含进这段程序,我们可以利用

gcc -E test.c -o test.i  //test为生成的.c文件名

命令来生成预处理过的.i文件。-E选项代表让gcc在预处理阶段后停止编译。

预处理规则

  1. 删除代码中的“#define”,展开所有宏定义;
  2. 处理条件编译指令,如#if、#ifdef、#undef等;
  3. 将由“#include”包含的文件插入到预编译指令对应的位置,若文件中包含其它文件,同样进行替换;
  4. 删除代码中的注释;
  5. 添加行号和文件标识;
  6. 保留#pragma编译器指令。

b.编译(Compilation)

        这个阶段gcc会对经过预处理的文件进行语法、词法和语义分析,确定代码实际要做的工作,若检查无误,则生成相应的汇编代码文件。

        主要作用是对预编译后的.i文件编译,生成汇编代码的.s文件。

        gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。我们可以使用-S选项来进行查看,该选项只进行编译而不进行汇编过程,生成汇编代码。可以利用

gcc -S test.i -o test.s

命令进行编译过程。

c.汇编(Assembly)

        汇编过程将编译后生成的汇编代码转换为机器可以执行的命令,即二进制指令,每一个汇编语句几乎都会对应一条机器指令。该阶段是将编译后的.s文件转化成二进制文件.o的过程,利用-c选项就可以生成二进制.o文件。可以利用

 gcc -c test.s

生成二进制代码test.o或利用

gcc -c test.s -o t.o

生成指定名称二进制代码t.o。

d.链接(Linking)

        链接过程是组装各个目标文件的过程,在这个过程中会解决符号依赖和库依赖关系,最终生成可执行文件。该阶段主要将成功编译的二进制文件进行链接操作,生成可执行文件。利用

gcc test.o -o test

生成可执行文件test。

e.运行
./test 
f.执行效果

二、GDB

1.GDB的介绍

        GDB可以逐条执行程序、操控程序的运行,并且随时可以查看程序中所有的内部状态,如各变量的值、传给函数的参数、当前执行的语句位置等,藉此判断代码中的逻辑错误。

        所有的程序在写好以后,都要经过调试,在调试过程中发现并改正程序中的错误。如果没有GDB,程序员为了跟踪某些错误,就要在程序中加入大量的语句,用来产生一些特定的输出。对于某些程序来说,这样做会导致更多的错误。

2.GDB的使用

(1).启用GDB

//例:编写程序源代码为hello.c
gcc hello.c -o hello -g  // -g 在代码中加入调试信息
gdb hello [-选项]		 //启动GDB并载入程序

(2).GDB常用调试命令

(3).TUI模式

        TUI(terminal user interface,终端用户界面)模式,比较直观的显示参数,按组合键Ctrl+X+A切换。

//改变窗口布局
layout prev | next | LAYOUT-NAME
src:Displays source and command windows. // 显示源码和命令窗口。
asm:Displays disassembly and command windows. // 显示汇编和命令窗口。
split:Displays source, disassembly and command windows. // 显示源码、汇编和命令窗口。
regs:Displays register window. // 显示寄存器窗口。

(4).常见使用步骤

(1)gdb程序

(2)列出程序代码,并设置断点

(3)运行程序

(4)查看变量值

(5)设置监听变量

(6)继续执行

(7)结束调试

三、Makefile

1.基本概念

        Makefile是GNU make程序在执行的时候默认读取的配置文件。Makefile记录了文件之间的依赖关系,通过比对目标文件和依赖文件的时间戳,决定是否需要执行相应的命令;同时,Makefile还可以定义变量,接收用户传递的参数变量,通过这些元素的相互配合,省去了繁杂的编译命令,不仅节省时间,也减小了出错的概率。

        Makefile主要包含了以下五个部分:显式规则、隐晦规则、变量的定义、文件指示、 注释。

        Makefile文件内容的主体由很多规则构成,每一条规则都由三部分组成:

                (1)目标(Object):表明输出的目标

                (2)依赖(Dependency):输出目标的依赖对象

                (3)命令(Command):生成目标需要执行的命令


        make是一个命令工具,用于解释Makefile中的指令。Makefile是一个文件,用来告诉make命令如果编译整个工程生成程序集。只需编写Makefile文件,然后再Makefile所在目录执行make命令即可。

        Make的工作流程

                ① 查找当前目录下的Makefile文件;
                ② 初始化Makefile文件中的变量;
                ③ 分析Makefile中的所有规则;
                ④ 为所有的目标文件创建依赖关系;
                ⑤ 根据依赖关系决定哪些目标文件要重新生成;
                ⑥ 执行生成命令。

2.使用方法

(1).基本格式

a.make命令
//make命令
make [选项] [Makefile文件]
make clean

b.Makefile文件
//Makefile 文件格式
目标 .. : 依赖 ...
<Tab>命令   //命令前必须是Tab,否则会出错
#  解释格式:[符号]	 [作用]
# 	#  	注释
# 	[] 	可替代的内容
# 	?= 如果没有被赋值过就赋予等号后面的值
# 	+= 	添加等号后面的值
# 	= 	最基本的赋值(最后才展开)
# 自动变量
# 	$@ 	指代当前目标,make 命令当前构建的那个目标。比如,make foo 的 $@ 就指代 foo。
# 	$< 	指代第一个依赖条件。比如,规则为 t: p1 p2,那么 $^ 就指代 p1 p2 。
#	$^ 	指代所有前置条件,之间以空格分隔,不包含重复的依赖条件。 
#	$* 	指代匹配符 % 匹配的部分,即不包含扩展名的目标文件名称。比如 %.txt 匹配 f1.txt 中的 f1 ,$* 就表示 f1。
# version 1
[可执行文件名]:[1.cpp] [2.cpp] [3.cpp] [...]
    gcc/g++ -o [可执行文件名] [1.cpp] [2.cpp] [3.cpp] [...]

#version 2
[变量例:CC] = g++/gcc  
[变量例:TARGET] = [可执行文件名]
[变量例:OBJ]: [链接文件:1.o] [2.o] [...] 

$(TARGET) : $(OBJ)
    $(CC) -o $(TARGET) $(OBJ)

[1.o]: [1.cpp]
    $(CC) -c [1.cpp]

[1.o]: [1.cpp]
    $(CC) -c [1.cpp]
    
[...]

#version 3
[变量例:CC] = g++/gcc
[变量例:TARGET] = [可执行文件名]
[变量例:OBJ]: [链接文件:1.o] [2.o] [...] 

[变量例:FLAGS] = [编译选项:-c -Wall]  # -Wall 警告

$(TARGET) : $(OBJ)
    $(CC) -o $@ $^
%.o:%.cpp
    $(CC) $(FLAGS) $< -o $@

.PHONY clean   #防止存在文件名为clean
clean: 
    rm -f *.o $(TARGET)

#version4
[变量例:CC] = g++/gcc
[变量例:TARGET] = [可执行文件名]
[变量例:SRC] = $(wildcard *.cpp)
[变量例:OBJ] = $(patsubst %.cpp,%.o,$(SRC))

[变量例:FLAGS] = [编译选项:-c -Wall] 

$(TARGET) : $(OBJ)
    $(CC) -o $@ $^
%.o:%.cpp
    $(CC) $(FLAGS) $< -o $@

.PHONY clean   #防止存在文件名为clean
clean: 
    rm -f *.o $(TARGET)
c. 执行效果

 

  • 35
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值