Linux 基本开发工具的使用(yum、vim、gcc、g++、gdb、make/makefile) ...

打印 上一主题 下一主题

主题 900|帖子 900|积分 2700

Linux 软件包管理器 - yum

理解什么是软件包和yum

1)Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可实行程序。但是如许太麻烦了,于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装。
2)软件包和软件包管理器,就好比 “App” 和 “应用商店” 如许的关系。
3)yum (Yellow dog Updater, Modified) 是 Linux 下非经常用的一种软件包管理器( Linux 下提供的一个软件管家,大概叫做应用商店)。主要应用在Fedora, RedHat,Centos 等发行版上。我们可以通过 yum ,搜素、安装或卸载对应的软件。
4)由于 yum 是从远端服务器上下载 RPM 包,以是在下载时必须联网,而我们可以通过 ping 指令查看当前云服务器是否联网。

留意:一个服务器同一时刻只允许一个yum进行安装,不能在同一时刻同时安装多个软件。
如何查看/查找软件包

指令:yum list
功能:yum list 指令默认罗列出可供下载的全部软件。

说明
1)软件包名称:主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构。
2)"x86_64(体系结构)"后缀表示64位系统的安装包,"i686"后缀表示32位系统安装包,选择包时要和系统匹配。
3)"el8"表示操作系统发行版的版本,“el8"表示的是"centos8/redhat8”,“el7"表示"centos7/redhat7”。
4)最后一列表示的是“软件源”的名称,类似于“小米应用商店”,“华为应用商店”如许的概念。
默认罗列出所有软件时数目有很多,而这时我们可以使用管道 | 和 行过滤指令 grep 进行过滤搜索
这里我们以查找 lrzsz 为例:
   lrzsz 可以将 Windows 当中的文件上传到 Linux 当中,也可以将 Linux 当中的文件下载到 Windows 当中,实现云服务器和本地机器之间进行信息互传。
  查找 lrzsz : yum list | grep lrzsz

实行以上命令之后,系统就可以直接在众多的软件源当中帮我们进行过滤搜素 lrzsz 。
如何安装软件

指令: sudo yum install 软件名
   [jack@VM-8-12-opencloudos ~]$ sudo yum install lrzsz
  实行以上指令后,yum 会自动找到都有哪些软件包必要下载,这时间大概会询问你是否确认安装,如果确认,敲 “y” 确认即可,当出现 “complete” 字样时,说明安装完成。
如果你不想系统询问你,你可以实行 sudo yum install -y 软件名,此时系统便会不询问而直接安装成功。
留意
1)安装软件时由于必要向系统目次中写入内容,一般必要 sudo 大概切换到 root 账户下才能完成。
2)yum 安装软件只能一个装完了再装另一个,正在使用 yum 安装一个软件的过程中,如果再实验用 yum 安装另外一个软件,yum 就会报错。
如何实现本地机器和云服务器之间的文件互传

上面我们安装了 lrzsz 软件,如今我们可以来看一下这个软件怎么用。
lrzsz 这个工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件,安装完毕之后可以通过拖拽的方式将文件上传过去。如下:

拖拽上传完毕后,ll / ls 我们就可以看到当前目次存在这个文件了

当然,除了拖拽的方式,我们也可以通过下面的方式来完成本地机器和云服务器之间的文件互传:
1)指令:rz -E
通过该指令可选择必要从本地机器上传到云服务器的文件。

2)指令: sz 文件名
该指令可将云服务器上的文件下载到本地机器的指定文件夹。

如何卸载软件

指令: sudo yum remove 软件名
   [jack@VM-8-12-opencloudos ~]$ sudo yum remove lrzsz
  当实行以上命令后,yum会自动卸载该软件,这时间系统也会询问你是否确认卸载,如果确认,敲 “y” 确认卸载即可,当出现 “complete” 字样时,说明卸载完成。
同样,如果你不想系统询问你,你可以实行 sudo yum remove -y 软件名,此时系统便会不询问而直接卸载软件成功。
Linux 编辑器 - vim 的使用

vim 的基本概念

vim 本质上是一个功能强大,多模式的文本编辑器,在我们进行开发的时间,主要办理我们编写代码的题目。
下面我们主要介绍 vim 最常用的三种模式:命令模式(Normal mode)插入模式(Insert mode)底行模式(last line mode)
1)正常/普通/命令模式(Normal mode)
在命令模式下,我们可以控制屏幕光标的移动,字符、字或行的删除,复制粘贴,剪贴以及进入Insert mode下,大概到 last line mode下等操作。
2)插入模式(Insert mode)
只有在插入模式下才能进行笔墨输入,按「Esc」键可回到命令行模式,该模式是我们使用最频繁的编辑模式。
3)底行模式(Command mode)
在底行模式下,我们可以将文件保存或退出,大概进行文件替换,也可以进行查找字符串、列出行号等操作。在底行模式下我们还可以直接输入vim help-modes 查看当前vim的所有模式。
vim 的基本操作

指令:vim 文件名
作用:进入文件进行编辑
   [jack@VM-8-12-opencloudos ~]$ vim test.cpp
  vim 进入文件后默认为命令模式(普通模式),如果要输入笔墨则需切换到插入模式。

命令模式 切换至 插入模式
1)按 i 键:在当前光标处进入插入模式。
2)按 a 键:在当前光标的后一位置进入插入模式。
3)按 o 键:在当前光标处新起一行进入插入模式。
命令模式 切换至 底行模式
1)按 Shift + : 即可,实际上就是输入 :
插入模式 或 底行模式 切换至 命令模式
1)插入模式或是底行模式切换至命令模式都是直接按一下 Esc 键即可。
vim 命令模式各命令汇总

【移动光标】
1)按 k :光标上移。
2)按 j :光标下移。
3)按 h :光标左移。
4)按 l :光标右移。
5)按 $(Shift + 4 = $) :移动到光标所在行的行尾。
6)按 ^ (Shift + 6 = ^):移动到光标所在行的行首。
7)按 gg :移动到文本开始。
8)按 Shift+g(G) :移动到文本末尾。
9)按 n(行号)+Shift+g(n(详细数字) + G) :移动到第n行行首。
10)按 n+Enter :当前光标向下移动n行。
11)按 w :光标从左到右,从上到下的跳到下一个字的开头。
12)按 e :光标从左到右,从上到下的跳到下一个字的结尾。
12)按 b :光标从右到左,从下到上的跳到上一个字的开头
【删除】
1)按 x :删除光标所在位置的字符。
2)按 nx :删除光标所在位置开始今后的n个字符。
3)按 X :删除光标所在位置的前一个字符。
4)按 nX :删除光标所在位置的前n个字符。
5)按 dd :删除光标所在行。
6)按 ndd :删除光标所在行开始往下的n行。
【复制粘贴】
1)按 yy :复制光标所在行到缓冲区。
2)按 nyy :复制光标所在行开始往下的n行到缓冲区。
3)按 yw :将光标所在位置开始到字尾的字符复制到缓冲区。
4)按 nyw :将光标所在位置开始今后的n个字复制到缓冲区。
5)按 p :将已复制的内容在光标的下一行粘贴上。
6)按 np :将已复制的内容在光标的下一行粘贴n次。
【剪切】
1)按 dd :剪切光标所在行。
2)按 ndd :剪切光标所在行开始往下的n行。
3)按 p :将已剪切的内容在光标的下一行粘贴上。
4)按 np :将已剪切的内容在光标的下一行粘贴n次。
【撤销】
1)按 u :撤销。
2)按 Ctrl+r :恢复刚刚的撤销。
【巨细写切换】
1)按 ~ :完成光标所在位置字符的巨细写切换。
2)按 n~ :完成光标所在位置开始今后的n个字符的巨细写切换。
【替换】
1)按 r :替换光标所在位置的字符。
2)按 R :替换光标所到位置的字符,直到按下「Esc」键为止。
【更改】
1)按 cw :将光标所在位置开始到字尾的字符删除,并进入插入模式。
2)按 cnw :将光标所在位置开始今后的n个字删除,并进入插入模式。
【翻页】
1)按 Ctrl+b :上翻一页。
2)按 Ctrl+f :下翻一页。
3)按 Ctrl+u :上翻半页。
4)按 Ctrl+d :下翻半页。
vim 底行模式各命令汇总

在使用底行模式之前,先按 Esc 键确定你已经处于命令模式,再按 Shift + : 即可进入底行模式
【行号设置】
1) set nu :表现行号。
2) set nonu :取消行号。
【保存退出】
1) w :保存文件。
2) q :退出 vim,如果无法离开 vim,可在 q 背面跟一个 ! (即 q!)表示欺凌退出。
3) wq :保存退出。
【分屏指令】
1) vs 文件名 :实现多文件的编辑。
2) Ctrl+w+w :光标在多屏幕下进行切换。
【实行指令】
1) !+指令 :在不退出vim的情况下,可以在指令前面加上 ! 就可以实行 Linux 的指令,比方查看目次、编译当前代码等。
vim 的简单设置

设置文件的位置
1)在目次 /etc/ 下面,有个名为 vimrc 的文件,这是系统中公共的设置文件,对所有效户都有效。
2)在每个用户的主目次 /home/xxx 下,都可以自己创建私有的设置文件,定名为 “.vimrc” ,这是该用户私有的设置文件,仅对该用户有效。
比方,普通用户在自己的主目次下创建了 “.vimrc” 文件后,在文件当中输入 set nu 指令并保存,下一次打开vim 的时间就会自动表现行号。
vim 的设置比较复杂,某些 vim 设置还必要使用插件,发起不要自己一个个去设置。比较简单的方法是直接在 shell 中实行以下指令(想在哪个用户下让 vim 设置见效, 就在哪个用户下实行这个指令. 剧烈 “不推荐” 直接在 root 下实行):
   curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh
  实行之后必要按照提示输入 root 暗码. 您的 root 暗码不会被上传, 请放心输入.

然后等待安装设置,最后手动实行 source ~/.bashrc 即可。

设置完成后,像什么自动补全、行号表现以及自动缩进什么的就都有了。
   留意:以上的一键设置目前只支持 Centos7 x86_64. 如果你的系统不是 Centos7 x86_64. 只能像小编一样前去你自己的服务器中重装系统切换镜像到 Centos7 x86_64. 否则就只能手动设置 vim (网上搜有,不过比较麻烦,还有一些插件)

  Linux 编译器 - gcc / g++ 的使用

gcc / g++ 的作用

gcc 和 g++ 分别是 GNU 的 C 和 C++ 的编译器,gcc 和 g++ 在实行编译的时间一般有以下四个步调:
1)预处理(头文件睁开、去解释、宏替换、条件编译)。( 文件后缀:.i )
2)编译(把C代码翻译成汇编语言)。(文件后缀:.s)
3)汇编(汇编代码转为二进制可重定位目标代码)。(文件后缀:.o)
4)链接(将汇编过程产生的二进制代码进行链接)。
gcc / g++ 语法

语法: gcc/g++ [选项] 要编译的文件 [选项] [目标文件]
常用选项:
1)-E 只进行预处理,这个不生成文件,你必要把他重定向到一个输出文件内里(否则将把预处理后的效果打印到屏幕上)。
2)-S 编译到汇编语言,不进行汇编和链接,即只进行预处理和编译。
3)-c 编译到目标代码 (汇编语言翻译成二进制目标文件)
4)-o 将处理效果输出到指定文件,该选项后需紧跟输出文件名。
5)-static 此选项对生成的文件采取静态链接。
6)-g 生成调试信息(若不携带该选项则默认生成release版本)。
7)-shared 此选项将只管使用动态库,生成文件较小。
8)-w 不生成任何告诫信息。
9)Wall 生成所有告诫信息。
10)-O0/-O1/-O2/-O3 编译器优化选项的四个级别,-O0 表示没有优化,-O1 为缺省值,-O3 优化级别最高。
辅助影象:E(预处理),S(编译),c(汇编):ESc ->键盘左上角的 Esc 键
预处理

指令:gcc -E test.c -o test.i
1)预处理功能主要包罗头文件睁开、去解释、宏替换、条件编译等。
2)预处理指令是以 # 开头的代码行。
3)-E 选项的作用是让 gcc/g++ 在预处理结束后停止编译过程。
4)-o 选项是指目标文件,“xxx.i” 文件为已经过预处理的原始程序。

编译

指令:gcc -S test.i -o test.s
1)在这个阶段中,gcc/g++ 首先检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,将代码翻译成汇编语言。
2)用户可以使用 -S 选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
3)-o选项是指目标文件,“xxx.s” 文件为已经过翻译的原始程序。

汇编

指令:gcc -c test.s -o test.o
1)汇编阶段是把编译阶段生成的 “xxx.s” 文件转成目标文件
2)读者在此可使用选项 “-c” 就可看到汇编代码已转化为 “xxx.o” 的二进制目标代码了

小贴士:实行 od test.o 就能以二进制代码的方式查看原来的 test.o 文件。
留意:这里的二进制文件(可重定向目标二进制)还不能实行,必要链接之后才能变成可实行文件。链接形象来说就是:把你写的代码和 c/cpp 标准库中的代码合起来。
链接

指令:gcc test.o -o test
1)在成功完成以上步调之后,就进入了链接阶段。
2)链接的主要使命就是将生成的各个 “xxx.o” 文件进行链接,生成可实行文件。
3)gcc/g++ 不带 -E、-S、-c 选项时,就默认生成预处理、编译、汇编、链接全过程后的文件。
4)若不用 -o 选项指定生成文件的文件名,则默认生成的可实行文件名为 a.out。

留意:链接后生成的也是二进制文件
   想相识更多的更详细内容点击这里。
  静态库和动态库

以上内容我们涉及到了一个函数库的内容,我们知道我们的 C 程序中,并没有定义“printf” 函数的实现(我们打代码 printf 并不是实现 printf 函数,而是调用 printf 函数),且在预编译中包罗的 “stdio.h” 头文件中也只有该函数的声明,而没有定义函数的实现,那是在哪里实现 “printf” 函数的呢?
答案是:系统把这些函数实现都写到一个名为 libc.so.6 的库中,在没有指定时,gcc 会到系统默认的搜索路径 “/usr/lib” 下进行查找,然后链接到 libc.so.6 的库去,如许就有了 printf 函数的实现了,这也就是链接的作用。
这里我们引出了一个函数库的内容,而函数库一般分为静态库动态库两种: Windows下静态库后缀名一般为 .lib 动态库后缀名一般为 .dll
   1)静态库是指编译链接时,把库文件的代码全部加入到可实行文件中,因此生成的文件比较大,但在运行时也就不再必要库文件了,静态库后缀名一般为 “.a” 。
2)动态库与之相反,在编译链接时并没有把库文件的代码加入到可实行文件中而是在程序实行时由运行时链接文件加载到库,如允许以节流系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库.gcc 在编译时默认使用动态库完成了链接之后,gcc 就可以生成可实行文件。
  动态链接:
 优点:省空间(节流资源,磁盘的空间,内存的空间),bin 体积小,加载速率快(运行时加载到内存中) 。
 缺点:依靠动态库,程序可移植性较差。
静态链接:
 优点:不依靠第三方库(形成可实行程序以后),程序的可移植性较高
 缺点:浪费空间。
gcc / g++ 默认生成的二进制程序是动态链接的,这点我们可以通过 file 命令来验证:

其次,我们还可以使用 ldd 指令查看动态链接的可实行文件所依靠的库。

小贴士:上面图中的 /lib64/libc.so.6 就是当前云服务器当中的C标准库。
固然 gcc和g++ 默认采取的是动态链接,但是如果我们想要使用静态链接,带上 -static 选项就可以实现。
指令:gcc test.c -o test_s -static
   小贴士:如果上面这条指令无法实行,则必要安装静态库 g++ 和 gcc 的选项、动静态库链接没有任何差别,大概必要下载静态库libc.a
安装C静态库 & C++ 静态库指令如下:
C 静态库:sudo yum install -y glibc-static
C++静态库:sudo yum install -y libstdc+±static
  实行上面指令后生成的可实行文件便是静态链接的了:

我们通过对比源代码雷同,但链接方式差别而生成的两个可实行程序 test 和 test_s 的巨细,可以看到静态链接的文件巨细比动态链接的文件的巨细大很多,这也验证了动态链接比较节流空间,而静态链接比较浪费空间这点。

Linux 调试器 - gdb 的使用

gdb 的安装

当我们第一次使用 gdb 的时间,系统会告知我们命令找不到,这时间我们就必要自行安装一下 gdb :
指令:sudo yum install -y gdb
gdb 的背景

进入 gdb:
指令:gdb 可实行程序文件名
程序发布方式:
 1)debug版本:程序本身会被加入更多的调试信息,以便于进行调试。
 2)release版本:不会添加任何调试信息,是不可调试的。
小贴士:在 Windows下的 VS 想要调试也必要在 debug 模式下。
   拓展:为什么有了debug 版本,还要有 release 版本呢?(为什么要有两个版本呢)
release 是给客户去用的,而对于程序员,要经常进行代码编写、调试代码等等,那就必须以 debug 版本发布来包管他的程序是便于调试的,而作为客户不必要关心debug,客户不必要得到他不必要的东西。程序员必要调试,而用户用不到也不关心。
release 版本只是单纯软件的功能,没有加任何的调试信息。
  在Linux当中 gcc/g++ 默认生成的可实行程序是 release 版本的,是不可被调试的(包罗 l 看不了代码,r 也跑不起来)。如果想生成 debug 版本,就必要在使用 gcc/g++ 生成可实行程序时加上 -g 选项:


对同一份源代码分别生成其 release 版本和 debug 版本的可实行程序,可以看到,debug 版本发布的可实行程序的巨细比 release 版本发布的可实行程序的巨细要大一点,其缘故起因就是以 debug 版本发布的可实行程序当中包罗了更多的调试信息:

gdb 指令汇总

我们先来写一个程序,下面所有操作都基于这个程序:

进入gdb
指令: gdb 可实行程序文件名
调试
1)run / r :运行代码(启动调试),有断点在断点处停下来。

2)next / n :逐过程调试。

3)step / s :逐语句调试。(碰到函数会进入函数内里)

4)until 行号:跳转至指定行。
可以用于跳出循环。
5)finish:实行完当前正在调用的函数后停下来(不能是主函数)。
不进入函数调试,也不从一个断点运行到下一个断点,只单纯把这一个函数跑完。
finsh 方便我们快速把代码跑完,排查代码题目。(直接进入函数,finsh,如果代码有误会直接停下来,就不用在函数内里逐语句排查题目,方便我们快速找到代码堕落的范围)
6)continue / c :运行到下一个断点处。(有多个断点时由一个断点运行到下一个断点)
7)set var 变量=x:修改变量的值为x。
表现
1)list / l n:表现从第n行开始的源代码,每次表现10行,若n未给出则默认从上次的位置往下表现.。

2)list / l 函数名:表现该函数的源代码。
3)print / p 变量:打印变量的值。
4)print / p &变量:打印变量的地址。
5)print / p 表达式:打印表达式的值,通过表达式可以修改变量的值。
6)display 变量:将变量加入常表现(每次停下来都表现它的值)。
类似于 Windows下的窗口,用于监控变量。
7)display &变量:将变量的地址加入常表现。
8)undisplay 编号:取消指定编号变量的常表现。(记住是编号)
类似于 Windows下的取消窗口,不想再监控这个变量了。就取消。
9)bt:查看各级函数调用及参数。(查看函数的调用堆栈)

10)info / i locals:查看当前栈帧当中局部变量的值。
断点
1)break / b n:在第n行设置断点。

2)break / b 函数名:在某函数体内第一行设置断点。
3)info breakpoint / b:查看已打断点信息。

4)delete / d 编号:删除指定编号的断点。(编号不是行号,记住了)

5)disable 编号:禁用指定编号的断点。(保留陈迹,断点不见效)
disable 之后,再次 info b,对应断点的 Enb 那项表现 n;见效的表现 y。可以看看上图。
6)enable 编号:启用指定编号的断点。
退出gdb
1)quit / q:退出gdb。
gdb 操尴尬刁难标于Windows下 IDE(vs2022等等)的调试操作


留意:以上 IDE 调试有些电脑必要配合 Fn 按键一起才能见效。
Linux 项目自动化构建工具 - make/Makefile 的使用

make / Makefile 的紧张性

1)会不会写 Makefile / makefile,从侧面说明了一个人是否具备完成大型工程的本事。
2)一个工程的源文件不可胜数,按照其类型、功能、模块分别放在若干个目次当中,Makefile 定义了一系列的规则来指定:哪些文件必要先编译,哪些文件必要后编译,甚至于进行更复杂的功能操作。
3)Makefile 带来的好处就是“自动化编译”,一旦写好,只需一个 make 命令,整个工程完全自动编译,极大的提高了软件开发的效率。
4)make 是一个命令工具,是一个解释 Makefile 当中指令的命令工具,一般来说,大多数的 IDE 都有这个命令,比方:Delphi 的 make,Visual 中 C++的 nmake,Linux 下 GNU 的 make。可见,Makefile都成为了一种在工程方面的编译方法。
5)make是一条命令,Makefile是一个文件,两个搭配使用,完成项目自动化构建。
依靠关系和依靠方法

在使用 make / Makefile 前我们首先应该理解各个文件之间的依靠关系以及它们之间的依靠方法。
1)依靠关系: 文件A的变更会影响到文件B,那么就称文件B依靠于文件A。
比方,test.o 文件是由 test.c 文件通过预处理、编译以及汇编之后生成的文件,以是 test.c 文件的改变会影响test.o,以是说 test.o 文件依靠于 test.c 文件。
2)依靠方法: 如果文件B依靠于文件A,那么通过文件A得到文件B的方法,就是文件B依靠于文件A的依靠方法。
比方,test.o 依靠于 test.c,而 test.c 通过 gcc -c test.c -o test.o指令就可以得到 test.o,那么 test.o 依靠于test.c 的依靠方法就是 gcc -c test.c -o test.o 。
多文件编译

当你的工程当中有多个源文件的时间,我们可以直接使用 gcc 指令对多个源文件进行编译,进而生成可实行程序:

但是进行多文件编译的时间一般不使用源文件直接生成可实行程序,而是先用每个源文件各自生成自己的二进制文件,然后再将这些二进制文件通过链接生成可实行程序。

   缘故起因:
1)若是直接使用源文件生成可实行程序,那么此中一个源文件进行了修改,再生成可实行程序的时间就必要将以是的源文件重新进行编译链接。
2)而若是先用每个源文件各自生成自己的二进制文件,那么此中一个源文件进行了修改,就只需重新编译生成该源文件的二进制文件,然后再将这些二进制文件通过链接生成可实行程序即可。
留意: 编译链接的时间不必要加上头文件,因为编译器通过源文件的内容可以知道所需的头文件名字,而通过头文件的包罗方式( “尖括号” 包罗和 “双引号” 包罗),编译器可以知道应该从何处去探求所需头文件。
  但是题目来了:如果源文件有很多,我们每次重新生成可实行程序时,所需输入的gcc 指令的长度与个数也会随之增长,这时我们就必要使用 make 和 Makefile 了,这将大大减少我们的工作量。
那如何使用 make / makefile 呢?
步调一: 在源文件所在目次下创建一个名为 makefile / Makefile 的文件。
步调二: 编写 makefile 文件。
makefile 文件最简单的编写格式是,先写出文件的依靠关系,然后写出这些文件之间的依靠方法,依次写下去。
留意:依靠关系下面一行,必须是以 tab 键开头再写依靠方法。

编写完毕Makefile文件后保存退出,然后在命令行当中实行make指令便可以生成可实行程序,以及该过程产生的中心产物。

   Makefile文件的简写方式:
$@:表示依靠关系中的目标文件(冒号左侧)。
$^:表示依靠关系中的依靠文件列表(冒号右侧全部)。
$<:表示依靠关系中的第一个依靠文件(冒号右侧第一个)。
比方上面 makefile 文件可以简写为:

说明: gcc / g++ 携带 -c 选项时,若不指定输出文件的文件名,则默认输出文件名为 xxx.o,以是这里也可以不用指定输出文件名。
  make 原理

   理解 makefile 的推导规则:
先看一个例子:
当 makefile 内里的内容是:
mycode:mycode.o
gcc mycode.o -o mycode
mycode.o:mycode.s
gcc -c mycode.s -o mycode.o
mycode.s:mycode.i
gcc -S mycode.i -o mycode.s
mycode.i:mycode.c
gcc -E mycode.o -o mycode.i

实行make 的时间;序次是
gcc -E mycode.o -o mycode.i
gcc -S mycode.i -o mycode.s
gcc -c mycode.s -o mycode.o
gcc mycode.o -o mycode
以是 makefile 从上往下扫描的时间,并不会直接实行第一个依靠方法,因为 mycode.o并不存在,以是他会先去找 mycode.o ;以此类推。跟栈结构一样
  1)make 会在当前目次下找名字为 “Makefile” 或 “makefile” 的文件。
2)如果找到,它会找文件当中的第一个目标文件,在上面的例子中,它会找到 mytest 这个文件,并把这个文件作为最终的目标文件。
3)如果 mytest 文件不存在,或是 mytest 所依靠的背面的 test.o 文件和 main.o 文件的文件修改时间比 mytest文件新,那么它就会实行背面的依靠方法来生成 mytest 文件。
4)如果 mytest 所依靠的 test.o 文件不存在,那么 make 会在 Makefile 文件中探求目标为 test.o 文件的依靠关系,如果找到则再根据其依靠方法生成 test.o 文件(类似于堆栈的过程)。
5)当然,你的 test.c 文件和 main.c 文件是存在的,于是 make 会生成 test.o 文件和 main.o 文件,然后再用test.o 文件和 main.o 文件生成最终的 mytest 文件。
6)make 会一层又一层地去找文件的依靠关系,直到最终编译出第一个目标文件。
7)在探求的过程中,如果出现错误,比方最后被依靠的文件找不到,那么 make 就会直接退出,并报错。
项目清理

在我们每次重新生成可实行程序前,都应该将上一次生成可实行程序时生成的一系列文件进行清理,但是如果我们每次都手动实行一系列指令进行清理工作的话,未免有些麻烦,因为每次清理时实行的都是雷同的清理指令,这时我们可以将项目清理的指令也加入到 Makefile 文件当中。

留意: 一般将这种 clean 的目标文件设置为伪目标,用.PHONY修饰,伪目标的特性是:总是被实行。
像 clean 这种,没有被第一个目标文件直接或间接关联,那么它背面所定义的命令将不会被自动实行,但我们可以表现要 make 实行。

   拓展知识:

  编写 Linux 下的小程序 - 进度条

行缓冲区的概念

我们先来看一段代码:

对于上面的代码,各人并不陌生,当我们 gcc 编译以上代码以后,./实行可实行程序,可以看到程序先输出字符串 hello linux 然后休眠 10秒 之后结束运行。
那我们再来看一段代码:

我们可以看到,两段代码只相差了一个 \n 换行符,那当我们 gcc 编译以上代码以后,./实行可实行程序,看到的效果还是和上面一样吗?答案是否定的,该代码的运行效果是:先休眠10秒,然后再打印字符串hello linux,然后结束运行。为什么呢?这里我们可以看到了行缓冲区的存在。
上面第二段代码首先实行的仍旧是 printf ,再实行 sleep ;但是表现器对应的是行革新,即当缓冲区当中碰到 ’\n’ 或是缓冲区被写满才会被打印出来,而在第二份代码当中并没有 ’\n’ ,以是字符串 hello linux 先被写到缓冲区当中去了,然后休眠 10 秒后,直到程序运行结束时才将 hello linux 打印到表现器当中。\n 默认打印的时间往表现器上打,\n 叫行缓存。
在这里缓冲区我们不过多介绍,背面文章会详细说,我们这里只必要知道缓冲区就是一块内存即可,那如果我们实行第二段代码,想让 hello linux 立即打印出来,而不是休眠之后再打印,该怎么做呢?很简单,我们使用 fflush 函数革新一下缓冲区即可,如下:

\r (回车) 与 \n(换行)

\r: 回车,使光标回到当前行的行首。
\n: 换行,使光标下移一格(并没有回到行首)。在语言层面是回车换行。
Enter键:回车换行,等价于 \n + \r 。
我们知道 \r 是使光标回到本行行首,那么如果我们向表现器上写了一个数之后再让光标回到本行行首,然后再写一个数,不就相当于将前面一个数字覆盖了吗?
以是这里有一个题目:不使用 ’\n’ 进行换行怎么将缓冲区当中数据打印出来?
答案:我们可以使用 fflush 函数,该函数可以革新缓冲区,即将缓冲区当中的数据革新当表现器当中。
对此我们可以编写一个倒计时的程序(利用到 \r 覆盖和革新缓冲区的原理)。

留意:如果上面程序不革新缓冲区,则实行程序时什么都不会表现。
\r 让在输出下一个数之前都让光标先回到本行行首,就得到了倒计时的效果。

gcc 编译程序之后,./a.out 运行程序即可得到倒计时,各人可按上图自行运行试试。
进度条小程序

【百度笔试题】进度条: 不进行换行,从左至右依次变长
知道了 \r 这个概念我们就可以实现一个简单的进度条了。
代码

小贴士:上面用 usleep 函数的缘故起因是:sleep 函数以秒为单位,革新太慢了。
留意:
1)如果这里的程序不革新缓冲区,实行程序时什么都不会表现。
2)%100s 默认右对齐(如果用这个,进度条会从右往左打),%-100s 默认左对齐

3)关于转义字符:
留意 \ 为特别字符必要转义 ,\ 代表的就是
% 也是特别字符,也必要转义 ,%% 代表的就是 %

gcc 编译代码以后,./ 实行可实行程序的效果如下:

除此之外,我们还可以给进度条加上颜色,让进度条更好看。
代码:

gcc 编译代码以后,./ 实行可实行程序的效果如下:

这里是学习 printf 输出颜色的一个链接,感兴趣的可以看看。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

商道如狼道

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表