Linux(六)编译链接、gcc和gdb

【回顾】

        在(五)中,小编带领大家一起学习了文件查看和编辑命令,不知道大家还记得多少呢?

又忘记的或者记不清楚的朋友记得会看(五)昂!

一、编译链接

1、gcc,g++,gdb的安装

        有的朋友可能会问,gcc、g++、gdb都是什么呢,我们就要安装。

        gcc和g++大家应该可以猜到,gcc是运行C语言的工具,g++是运行C++的工具,而gdb则是调试工具。

        在知道它们都是什么之后,我们就要学习安装它们啦!

        类似于我们在(五)中安装vim,在命令行输入::sudo apt install gcc        /g++/gdb

        在安装过程中会让大家选择[y/n],大家输入y就好啦。

        小编在安装g++时,顺手截的图,大家可以参考一下

        有的小伙伴可能会出现有的安装包无法下载的问题,需要按照提示先输入sudo apt-get update,然后再输入sudo apt install gcc/g++/gdb就可以啦!

2、gcc分布编译链接

第一步——预编译gcc -E main.c(自己编写的.c文件) -o main.i(生成的.i文件)

第二步——编译gcc -S main.i(上一步的.i文件) -o main.s(生成的.s文件)

第三步——汇编gcc -c main.s(第二步的.s文件) -o main.o(生成的.o文件)

第四步——链接gcc main.o(第三步的.o文件) -o main(生成的.out文件)  

                  执行:./main     或者    全路径/main

执行main

3、编译链接过程

原理:

main.c通过预编译生成main.i文件

main.i通过编译生成main.s文件

main.s通过汇编生成main.o文件(可重定位的二进制目标文件)

链接就是将所有的.o文件,.a文件(静态库文件),.lib文件,.obj文件链接起来,生成.out文件(ELF格式的可执行文件)(在Windows系统是生成.exe文件)

        让我们一起总结一下:预编译生成.i文件(第一步),编译生成.s文件(第二步),即编译生成汇编指令,然后接下来当然就是汇编了,对汇编指令进行汇编,生成.o文件(第三步),即变成二进制指令(第三步),最后就是链接了(第四步)。

        小编在这里向大家重点强调这个编译链接过程非常的重要。大家必须要熟练掌握,不能出错。当面试官询问大家编译链接的过程是什么时,大家连这四个步骤都不能说正确就不会有接下来的问题了,因为已经被淘汰。

二、gcc的执行

1、gcc如何执行

路径+可执行文件名   或者      路径+可执行文件名 &(将进程放到后台执行); 

(补充)大家可以把可执行文件放到/usr/bin就可以省略路径了;

        这是为什么呢?

        大家可以想一下,为什么我们执行ls、pwd这些命令(本质也是人写的程序)可以不用加路径,这是因为它们在bin目录里,也就是它们的路径为/user/bin,我们在(二)中学习目录结构时,让大家记住过bin目录的作用是存放常用的命令(二进制可执行程序),当我们把程序放在这个路径下,就可以直接输入可执行文件名进行执行啦。

2、两步执行与一步执行

(一)两步执行

        将三步合为一步,即不经过预编译,编译,汇编三步,直接一步生成.o文件,然后链接执行:
        gcc -c main.c -o main.o(这一步在工作中常用,只编译,查看是否出现语法错误)
        gcc -o main main.o

(二)一步执行   

        将四步合为一步:gcc -o main main.c

 3、多文件的编译执行

        首先,大家要先准备多个文件,这里小编准备的是add(求和)、max(求最大值)、main(主函数),一共有五个文件,包含两个.h文件,三个.c文件。

//add.h
int add(int x, int y);

//add.c
int add(int x, int y)
{
    return x+y;
}

//max.h
int max(int x,int y);

//max.c
int max(int x, int y)
{
    return x>y?x:y;
}

//main.c
#include <stdio.h>
#include "./max.h"
#include"./add.h"//不写路径默认当前位置,写可以是相对路径"./add.h"也可以是绝对路径"/home/stu/quzijie/class03/test06"
int main()
{
    int a=10;
    int b=20;
    printf("a+b=%d\n",add(10,20));
    printf("a,b的最大值为%d\n",max(10,20));
    return 0;
}

执行:

(两步执行)

gcc -c main.c

gcc -o main main.c add.c max.c

这里可能会有小伙伴这样写:gcc -o main main.c,不能这样写哦,这个是错误的,因为在main.c里面还使用了add和max。

(一步执行) 

gcc -o main main.c add.c max.c

三、gdb调试

1、debug版本与release版本

debug版本:

在编译阶段会加入某些调试信息;

调试信息是在编译的过程中加入到中间文件.o文件的;

gcc -c main.c -g:生成包含调试信息的中间文件
gcc -o main main.o

一步执行:gcc -o main main.c -g 

release版本:

发行版本,没有调试信息;

gcc默认生成的为release版本,因此才需要上面的命令生成debug版本,然后才能使用gdb调试

2、gdb命令

这些命令希望大家可以经常使用,多多练习才能掌握。

gdb 可执行文件名

显示代码:l

加断点:b 行号

启动程序:r(运行之前一定要加断点)

查看断点信息:info break/info b

删除断点信息:delete 断点编号

单步执行:n

打印:p

显示:display 变量名

退出:q

(gdb命令——全)

I:显示main函数所在的文件的源代码

list 文件名:num显示文件名文件num行上下的源代码(多文件)

b 行号:给指定行添加断点

b 函数名:给指定函数的第一有效行添加一个断点

info break:显示断点信息;(info b)

delete 断点号:删除指定断点

r(run):运行程序

n(next):单步执行

c(continue):继续执行,直接执行到下一个断点处

s:进入将要被调用的函数中执行

finish:跳出函数;

q:退出调试

bt:显示函数调用栈

disable 断点号:将断点设定为无效的,不加断点号,将所有断点设置为无效

enable 断点号:将断点设定为有效的,不加断点号,将所有断点设置为有效;

p val:打印变量val的值

p &val:打印变量val的地址

pa+b:打印表达式的值

p arr(数组名):打印数组所有元素的值

p *arr@len:用指向数组的指针打印数组所有元素的值

display:自动显示,参数和p命令一样;

info display:显示自动显示信息

undisplay+编号:删除指定的自动显示

ptype val:显示变量类型

3、补充命令

多进程的调试命令:

(gdb) set follow-fork-mode mode

mode可以选择parent或者child,即:选择调试哪个进程

注意:未被跟踪调试的进程会直接执行结束;

多线程调试命令:

1)利用info threads查看线程信息;

2)thread id:调试目标id指定的线程;

3)set scheduler-locking off|on|step;

“off"表示不锁定任何线程;

“on"只有当前被调试的线程继续运行;

“step"在单步执行的时候,只有当前线程会执行;

4、总结调试命令步骤

(1)gcc -o main main.c -g 

(2)gdb 可执行文件名

(3)显示代码:l

(4)加断点:b 行号

(5)启动程序:r(运行之前一定要加断点)

(6)显示:display 变量名

四、makefile安装及make自动化编译

1、安装makefile

       还是和之前几次的安装方法一样,在命令行输入::sudo apt install make

        在安装过程中会让大家选择[y/n],大家输入y就好啦!

        上图是小编在安装makefile时的截图,大家可以参考一下。

        有的小伙伴可能会出现有的安装包无法下载的问题,需要按照提示先输入sudo apt-get update,然后再输入sudo apt install gcc/g++/gdb就可以啦!

2、makefile文件的运用

makefile文件:

        Linux上的工程管理工具,可以实现自动化编译;工程中的源文件不计其数,可以根据模块,功能等存储在不同的目录中;

        makefile可以提高编译效率,使用make命令每次只会编译那些修改了的或者依赖修改了的这些文件,没有修改的文件不会重新编译。

        VS底层就有自己的makefile文件;

我们还是使用上面引入的add、max、main的代码。

大家一起跟着小编动手写makefile文件吧!

        上面这个图片就是小编的练习成果啦,大家在自己编写的过程中一定要注意顶格与tab键,了解makefile文件的生成规则,在图片中小编也标注了让大家注意tab键与空格是不一样的,一定要注意字的颜色,以及生成规则!

3、总结

        makefile可以提高编译效率,使用make命令每次都只会编译那些修改了的或者依赖修改了的文件(间接修改),没有修改的文件不会重新编译;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值