【Linux】Linux工具

  1. 预处理(进行宏替换)
  2. 编译(生成汇编)
  3. 汇编(生成机器可识别代码)
  4. 连接(生成可执行文件或库文件)
gcc如何完成

gcc -o 编译完成的文件名 要编译的文件名, 指定编译完成的文件名

预处理(进行宏替换)
  • 预处理功能主要包括宏定义, 文件包含, 条件编译, 去注释等.
  • 预处理指令是以#开头的代码行
  • 实例: gcc -E hello.c -o hello.i
  • 选项-E, 该选项的作用是让gcc在预处理结束后停止编译过程
  • 选项-o是指目标文件, i文件为已经过预处理的C原始程序
编译(生成汇编)
  • 在这个阶段中, gcc首先要检查代码的规范性, 是否有语法错误, 以确定代码的实际要做的工作, 在检查无误后, gcc把代码翻译成汇编语言
  • 用户可以使用-S选项进行查看, 该选项只进行编译不进行汇编, 生成汇编代码
  • 实例: gcc -S hello.i -o hello.s
汇编(生成机器课识别代码)
  • 汇编阶段就是把编译器生成的.s文件转成目标文件
  • gcc -c hello.s -o hello.o, 将汇编代码转换成, 二进制目标代码了
链接
  • 在成功编译之后, 就进入链接阶段
  • 实例: gcc hello.o -o hello
在这里涉及到一个重要的概念: 函数库
  • 我们在C程序中, 并没有定义printf的函数实现, 且在预编译中包含的stdio.h中也只有函数的声明, 而没有定义函数的实现,那么是在哪里实现printf函数的呢?
  • 最后的答案是: 系统把这些函数实现定义到libc.so.6的库文件当中了, 在没有特别指定的时候, gcc会到系统默认的搜索路径usr/lib下进行查找, 也就是链接到libc.so.6库函数当中, 这样就能实现函数printf, 而这也是链接的作用
函数库一般分为静态库和动态库两种
  • 静态库是指编译链接时, 把库文件的代码全部加入到可执行文件当中, 因此生成的文件比较大, 但在运行时就不需要库文件了. 其后缀一般是.a
  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀为.so, 如前面所述的libc.so.6就是动态库。gcc在编译的时候默认使用动态库。完成了链接之后,gcc就可以生成可执行文件如下所示gcc hello.o -o hello
  • gcc默认生成二进制文件, 是动态链接的,这样可以通过file命令验证
gcc选项
  • -E 只激活预处理, 这个不生成文件, 你需要把他重定向到一个输出文件里面
  • -S 编译到汇编语言不进行汇编和链接
  • -c 编译到目标代码
  • static 对生成的文件采用静态链接
  • -g 生成调试信息,GNU调试器可利用该信息
  • -shared 此选项将尽量使用动态库,所以生成的文件比较小,但是需要系统有动态库
  • -O0
  • -O1
  • -O2
  • -O3 编译器的优化选项的4个级别,-O0没有没有任何优化,-O1为缺省值,-O3优化级别最高
  • -w不生成任何警告信息
  • -Wall生成所有警告信息
gcc选项记忆

esc iso

Linux项目自动化构建工具-make/Makefile

背景
  • 会不会写Makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录当中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,甚至进行更复杂的功能操作
  • makefile带来的一个好处就是—“自动化编译”, 一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令
  • make是一个指令,makefile是一个文件,两个搭配使用,完成项目自动化构建
理解

makefile是一个围绕依赖关系和依赖方法构建的一个自动化编译的工具,完成一件事情必须要有正确的依赖关系依赖方法

.PHONY:总是被执行的

如何得知是否需要重新进行执行呢?

通过对比时间来进行

实例

image-20230109174614006
依赖关系

  • 上面的代码file依赖file.o
  • file.o依赖file.s
  • file.s依赖file.i
  • file.i依赖file.c
原理
  • make是如何工作的,在默认方式下,也就是我们只输入make命令那么:
  1. make会在当前目录下找名字Makefilemakefile的文件
  2. 如果找到,它会找文件中的第一个目标文件,在上面的实例中,它会找file这个文件,并把这个文件作为最终的目标文件
  3. 如果file文件不存在,或是file所依赖的后面的file.o文件的修改时间要比file这个文件新,那么会执行后面定义的命令来生成file这个文件
  4. 如果file所依赖的file.o不存在,那么make会在当前文件中找目标文件file.o所依赖的如果找到再根据那一个规则生成hello.o文件(这一点像堆栈的过程)
  5. 这就是整个make的依赖性,make会一层又一层的去找文件的依赖关系,知道最终编译出一个目标文件
  6. 在寻找的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理
  7. make只管文件的依赖性,即,如果在找了依赖关系之后冒号后面的文件还是不存在,那就不工作了
项目清理
  • 工程是需要清理的
  • clean这种,没有被第一个目标文件直接或者间接的关联,那么后面定义的命令不会被自动执行,不过我们可以显示要make执行。即命令make clean来清楚所有的目标文件,以便重新编译
  • 但是一般我们这种clean目标文件,我们将它设置为伪目标,用.PHONY修饰,伪目标的特性是,总是被执行的

Linux第一个小程序 - 进度条

\r&&\n

理解回车和换行,回车是光标回到文档开头,换行是从上一行文档最后向下移动,然后回到文档开头

行缓冲区

什么现象?

首先打印出里面的内容,然后停顿3秒出现命令行

#include <stdio.h>
int main()
{
	printf("hello Makefile!\n");
	sleep(3);
	return 0;
}

什么现象?

#include <stdio.h>
int main()
{
	printf("hello Makefile!");
	fflush(stdout);// 刷新出缓冲区的内容
	sleep(3);
	return 0;
}

进度条代码

image-20230110191129053

使用git命令行

安装git
yum install git

git --version:查看安装git的版本

提交步骤:

  1. git add .,将需要用git管理的文件告知git
  2. git commit -m "信息", 提交改动到本地
  3. git push, 同步到远端服务器上

Linux调试器 - gdb使用

背景
  • 程序的发布方式有两种,debugrelease模式
  • Linux gcc/g++出来的二进制程序,默认是release模式
  • 要使用gdb,必须在源代码生成二进制的时候,加上-g选项
开始使用

如果直接使用gcc -o file file.c -std=c99显示是如下现象

image-20230111145106153

这是因为默认是release版本,不可以调试如果想要调试就要加上-g选项。

readelf -S 可执行程序名

readelf -S 可执行程序名 | grep -i debug :显示调试信息

image-20230111150304040

l(list) 1gdb模式下显示要调试的代码

r(run)gdb模式下启动程序并运行

b(breakpoint)行号:在指定行打断点

info b:查看断点

d 断点的编号:删除断点

disable breakpoint 断点编号, :设置指定断点为空断点

enable breakpoint 断点编号:开启断点

n(next):逐过程

s(step):逐语句

bt:查看调用栈

p 变量名:显示变量

display 变量名:显示要查看的变量

undisplay:取消对应的变量

until 行号:直接让代码跑到我们指定的行号

调试器的核心工作,主要是为了定位问题

所有显示指令不影响调试指令

finish:进入一个函数,只执行完函数,就停下来

c:从一个断点处运行至下一个断点处

set var n = xxx:设置某一个变量是特定值

enable breakpoint 断点编号:开启断点

n(next):逐过程

s(step):逐语句

bt:查看调用栈

p 变量名:显示变量

display 变量名:显示要查看的变量

undisplay:取消对应的变量

until 行号:直接让代码跑到我们指定的行号

调试器的核心工作,主要是为了定位问题

所有显示指令不影响调试指令

finish:进入一个函数,只执行完函数,就停下来

c:从一个断点处运行至下一个断点处

set var n = xxx:设置某一个变量是特定值

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值