当前位置: 首页 > article >正文

Linux:编译,调试和Makefile

一丶vim编译器

### 基本概念


模式:Vim有几种不同的模式,包括:


命令/正常/普通模式:控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode

插入模式:只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁 的编辑模式。

末行/底行模式:文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下,shift+: 即可进入该模 式。要查看你的所有模式:打开vim,底行模式直接输入

###基本操作

进入vim,在系统提示符号输入vim及文件名称后,就进入vim全屏幕编辑画面:

$ vim test.c 不过有一点要特别注意,就是你进入vim之后,是处于[正常模式],你要切换到[插入模式]才能够输入文 字。

[正常模式]切换至[插入模式]

输入a    输入i   输入o

[插入模式]切换至[正常模式]

目前处于[插入模式],就只能一直输入文字,如果发现输错了字,想用光标键往回移动,将该字删除,可 以先按一下「ESC」键转到[正常模式]再删除文字。当然,也可以直接删除。

[正常模式]切换至[末行模式] 「shift + ;」, 其实就是输入「:」 退出vim及保存文件,在[正常模式]下,按一下「:」冒号键进入「Last line mode」,例如:

: w (保存当前文件): wq (输入「wq」,存盘并退出vim) : q! (输入q!,不存盘强制退出vim)

注意:底行模式和插入模式无法直接切换

###命令模式命令集

光标移动

vim可以直接用键盘上的光标来上下左右移动,但正规的vim是用小写英文字母「h」、「j」、「k」、 「l」,分别控制光标左、下、上、右移一格 按

「G」:移动到文章的最后

按「 $ 」:移动到光标所在行的“行尾”

按「^」:移动到光标所在行的“行首”

按「w」:光标跳到下个字的开头

按「e」:光标跳到下个字的字尾

按「b」:光标回到上个字的开头

按「n l」:光标移到该行的第n个位置,如:5 l,56 l

按[gg]:进入到文本开始

按[shift+g]:进入文本末端 按「ctrl」+「b」:屏幕往“后”移动一页

按「ctrl」+「f」:屏幕往“前”移动一页

按「ctrl」+「u」:屏幕往“后”移动半页

按「ctrl」+「d」:屏幕往“前”移动半页

删除文字

「x」:每按一次,删除光标所在位置的一个字符

「n x」:例如,「6x」表示删除光标所在位置的“后面(包含自己在内)”6个字符

「X」:大写的X,每按一次,删除光标所在位置的“前面”一个字符 「n X」:例如,「20X」表示删除光标所在位置的“前面”20个字符

「dd」:删除光标所在行 「n dd」:从光标所在行开始删除#行

复制

「yw」:将光标所在之处到字尾的字符复制到缓冲区中。

「n yw」:复制#个字到缓冲区

「yy」:复制光标所在行到缓冲区。

「n yy」:例如,「6yy」表示拷贝从光标所在的该行“往下数”6行文字。

「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与“y”有关的复制命令都必须与“p”配合才能完 成复制与粘贴功能。

替换

「r」:替换光标所在处的字符。

「R」:替换光标所到之处的字符,直到按下「ESC」键为止。

撤销上一次操作

「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次“u”可以执行多次回 复。

「ctrl + r」: 撤销的恢复,撤销上一次撤销。

更改 「cw」:更改光标所在处的字到字尾处

「c n w」:例如,「c3w」表示更改3个字

跳至指定的行

「ctrl」+「g」列出光标所在行的行号。

「nG」:例如,「15G」,表示移动光标至文章的第15行行首

###vim末行模式命令集

在使用末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进入末行模式。

列出行号 「set nu」: 输入「set nu」后,会在文件中的每一行前面列出行号。

跳到文件中的某一行 「n」

:「n」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15, 再回车,就会跳到文章的第15行。

查找字符 「/关键字」: 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 「n」会往后寻找到您要的关键字为止。 「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直 按「n」会往前寻找到您要的关键字为止。 

保存文件 「w」: 在冒号输入字母「w」就可以将文件保存起来

离开vim 「q」:按「q」就是退出,如果无法离开vim,可以在「q」后跟一个「!」强制离开vim。 「wq」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。

       vim最后声明:Linux刚开始使用vim编译器使用起来感觉不如vs等编译器,可以搜索相关资料配置vim。

二丶gcc / g++

      这里只讲方法

 ###使用GCC编译源代码

      在终端中,使用以下命令编译hello.c

gcc hello.c -o hello

      这里,-o选项用于指定输出文件的名称。

###GCC编译链接过程

1. 预处理(Preprocessing)

      预处理阶段主要处理源代码中的宏定义、条件编译指令等。使用以下命令查看预处理后的代码:

gcc -E hello.c -o hello.i
2. 编译(Compilation)

      编译阶段将预处理后的代码转换为汇编代码。使用以下命令进行编译:

gcc -S hello.i -o hello.s
3. 汇编(Assembly)

       汇编阶段将汇编代码转换为机器代码。使用以下命令进行汇编:

gcc -c hello.s -o hello.o
4. 链接(Linking)

       链接阶段将编译生成的目标文件与库文件进行合并,生成可执行文件。在我们的例子中,使用以下命令进行链接:

gcc hello.o -o hello

        实际上,在第一步编译源代码时,GCC已经自动完成了预处理、编译、汇编和链接的过程。以上步骤只是为了说明编译链接的整个过程。

gcc 和 g++ 在这个过程几乎一样,差别也是细微的关于库那方面的差别

三丶调试:gdb

背景

程序的发布方式有两种,debug模式和release模式

Linux gcc/g++出来的二进制程序,默认是release模式

要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项

开始使用 gdb File 退出: ctrl + d 或 quit     

调试命令:

list/l 行号:显示File源代码,接着上次的位置往下列,每次列10行。

list/l 函数名:列出某个函数的源代码。

r或run:运行程序。

n 或 next:单条执行。

s或step:进入函数调用

break(b) 行号:在某一行设置断点

break 函数名:在某个函数开头设置断点

info break :查看断点信息。

finish:执行到当前函数返回,然后挺下来等待命令

print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数 

p 变量:打印变量值。

set var:修改变量的值

continue(或c):从当前位置开始连续而非单步执行程序

run(或r):从开始连续而非单步执行程序

delete breakpoints:删除所有断点

delete breakpoints n:删除序号为n的断点

disable breakpoints:禁用断点

enable breakpoints:启用断点

info(或i) breakpoints:参看当前设置了哪些断点

display 变量名:跟踪查看一个变量,每次停下来都显示它的值

undisplay:取消对先前设置的那些变量的跟踪

until X行号:跳至X行

breaktrace(或bt):查看各级函数调用及参数

info(i) locals:查看当前栈帧局部变量的值

quit:退出gdb

四丶Makefile

背景

        一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能操作 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编 译,极大的提高了软件开发的效率。

       make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命 令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一 种在工程方面的编译方法。 make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

###vim makefile

看图还是比较明了的,依赖文件列表也可以为空,就像clean一样,.PHONY 就像一个声明一样。

### make 和 make clean

       从上往下依次看,我们这个目录中只有makefile 和 一些源文件,先执行make命令,然后系统自动执行了g++命令,再看目录下的文件,多出来 .exe文件,并且可以执行,当我们再次执行make命令时被系统告知,.exe文件是最新的,因为如果每次执行make命令都编译一次没有修改的代码并且这些代码很长,源文件很多,就会很浪费时间和空间。

       紧接着我们执行了make clean命令,这里加上clean是因为make命令在读取makefile文件的时候默认从上往下读,不会执行makefile里面的所有的命令,写在前面的make就默认执行。同时注意,我们执行了多次make clean 命令,系统并没有警告,这就跟上面所说的.PHONY 有关了。

       这张图中,$@  和  $^  其中$ 符号默认,@代表标文件 myproject.exe,^代表所有的依赖文件,文件太多不想写可用。

       接下来我们可以看到makefile中一系列的目标文件,依赖文件和依赖关系,我们按照编译链接的逻辑将一整个g++ 流程拆分成 -E  -S  -c  得到 .i  .s .o 文件,上面提到make指令从上往下读取,但在这里make指令是按顺序执行代码,实际上是make找到了.exe 需要 .o ,然后向下找 .o 发现 .o文件没用生成,就继续执行,找到了可以生成.o 文件的 .s 文件,继续向下找需要的文件,执行完成后返回上一个文件继续执行,这个过程跟栈可以说是一模一样。

###最后的makfefile

  1 bin=myproject.exe
  2 src=myproject.cpp
  3 
  4 $(bin):$(src)
  5     g++ -o $@ $^
  6 
  7 .PHONY:clean
  8 clean:
  9     rm -f $(bin) 

       在makefile中可以定义变量,$ 是从bin 或者 src中提取内容 ,感觉就像指针和解引用一样,定义变量时等号两边最近的两个变量不可有空格,src可以跟多个cpp(或其他)变量,空格隔开,这种写法还是比较简单易懂的。


http://www.kler.cn/a/329234.html

相关文章:

  • Web开发:ORM框架之使用Freesql的DbFrist封装常见功能
  • Java-异步方法@Async+自定义分布式锁注解Redission
  • MATLAB绘制克莱因瓶
  • 记录java Collections.sort踩的坑
  • STM32 ADC --- 任意单通道采样
  • 在Qt(以及C++)中, 和 * 是两个至关重要的符号--【雨露均沾】
  • Spring MVC系统学习(一)——初识Spring MVC框架
  • AIGAME平台的由来与未来展望 —— 蒙特加密基金推动区块链与AI融合创新
  • Redis篇(应用案例 - 短信登录)(持续更新迭代)
  • GEE教程:利用sentinel-2数据和NDVI指数监测火灾
  • Ansible实现剧本远程服务器创建、删除用户
  • SpringGateway(网关)微服务
  • MDM监管锁系统上锁流程
  • Redis 中 String 命令的基础操作
  • 【CKA】一、基于角色的访问控制-RBAC
  • 【分布式微服务云原生】消息队列全解析:原理、应用场景与主流MQ对比
  • 基于Qt/C++UDP 调试软件功能及用途介绍
  • 蓝桥杯【物联网】零基础到国奖之路:十五. 扩展模块之双路ADC
  • Android 利用OSMdroid开发GIS 添加点、线、面和标记点
  • 【STM32】【rt-thread】C函数调用
  • 深入理解机器学习中的 K-均值聚类算法及其优缺点
  • mp取数据,模糊查询redis
  • 对于基础汇编的趣味认识
  • Ubuntu 安装RUST
  • spring-boot 整合 mybatis
  • 【ShuQiHere】深入理解微架构(Microarchitecture):LC-3 的底层实现 ️