桂平市住房和城乡建设局门户网站,如何检查网站是否被挂木马,曲靖网站推广,游戏加速器目录 Linux软件包管理器 - yum
Linux下安装软件包的方式
认识yum
查找软件包
安装软件 如何实现本地机器和云服务器之间的文件互传 卸载软件
Linux编辑器 - vim
vim的基本概念
vim下各模式的切换
批量化注释 vim的简单配置
Linux编译器 - gcc/g
gcc/g的作用
gcc/g语…目录 Linux软件包管理器 - yum
Linux下安装软件包的方式
认识yum
查找软件包
安装软件 如何实现本地机器和云服务器之间的文件互传 卸载软件
Linux编辑器 - vim
vim的基本概念
vim下各模式的切换
批量化注释 vim的简单配置
Linux编译器 - gcc/g
gcc/g的作用
gcc/g语法
预处理
编译 汇编
链接
静态库与动态库
Linux调试器 - gdb
gdb使用须知
gdb命令汇总
Linux项目自动化构建工具 - make/Makefile
make/Makefile的重要性
依赖关系和依赖方法
多文件编译
make原理
项目清理 Linux软件包管理器 - yum
在开始说yum之前我们先从Linux的角度解释什么是软件包
在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序.但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安 装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.软件包和软件包管理器, 就好比 App 和 应用商店 这样的关系. yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat, Centos等发行版上.
Linux下安装软件包的方式
在Linux下安装软件包的方法大概有以下三种 1下载到程序的源代码自行进行编译得到可执行程序。 2获取rpm安装包通过rpm命令进行安装。未解决软件的依赖关系 3通过yum进行安装软件。常用
那么解释一下这三种方法放到windows的环境下是怎么样的
1我们看到在GitHub上看到一个非常不错的开源项目软件你很想尝试一下你也可以直接下载别人打包好的安装包。也可以直接把别人的代码拿过来然后放到自己的编译器下自己进行编译使用得到可执行程序。这个过程就是方法1
2在Windows中通常通过下载.exe可执行程序或.msiWindows安装包文件进行安装。这些安装包通常自带图形化的安装向导简化了安装过程用户只需要运行安装程序即可。然而类似于RPM包的缺点Windows安装包也有可能在安装时没有自动处理所有的依赖关系尤其是一些比较老旧或者需要额外配置的程序。
举个例子假如你下载了一个软件的安装包.exe文件它可能会提示缺少某些依赖如特定的C运行库、.NET Framework等你就需要手动安装这些依赖项。
3简单明了就是直接去电脑自带的软件商店去下载。我的电脑下的就是这个。
认识yum
yumYellowdog Updater, Modified是Linux系统中的一个包管理工具也是的前端软件包管理器主要用于自动从软件仓库下载RPM包并且安装和更新软件包并自动解决软件包的依赖关系。它通常用于基于RPM的Linux发行版如CentOS、RHEL和Fedora。 注意一个服务器同一时刻只允许一个yum进行安装不能在同一时刻同时安装多个软件。 原因如下了解即可 锁定机制yum使用锁文件通常是/var/run/yum.pid来防止多个yum进程同时运行。这个锁文件确保只有一个yum进程可以访问和修改系统的包管理数据库。如果同时有多个yum进程运行它们可能会同时尝试修改同一个文件或数据库导致数据损坏或冲突。 依赖关系管理yum需要处理软件包的依赖关系、版本兼容性和冲突等问题。如果多个yum进程并行操作可能会导致依赖关系错误、安装冲突或卸载问题。例如一个进程可能安装了某个包的某个版本而另一个进程可能会尝试安装该包的不同版本造成系统不稳定。 事务管理yum会在安装、更新、卸载软件时执行事务即一系列操作。如果同时有多个进程进行软件管理可能会引发事务中的竞态条件race condition导致安装失败或部分安装成功这会对系统造成不一致的状态。 因为yum是从服务器上下载RPM包所以在下载时必须联网可以通过ping指令判断当前云服务器是否联网。 同样在Windows下也可以使用这样的指令查看自己想打游戏前网络的延迟是否正常看后面的time...ms)。 查找软件包
使用yum list指令可以罗列出可供下载的全部软件。
可以看到还是有很多很多的。 说明一下
1第一列为软件包名称其内容包括主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构。 2x86_64后缀表示64位系统的安装包i686后缀表示32位系统安装包选择包时要和系统匹配是要与你的云服务器匹配不是与你的主机电脑匹配。 3el7表示操作系统发行版的版本“el7表示的是centos7/redhat7”“el6表示centos6/redhat6”。 4最后一列表示的是“软件源”的名称类似于“小米应用商店”“华为应用商店”这样的概念。
由于包的数目可能非常之多, 这里我们需要使用 grep 命令只筛选出我们关注的包. 例如:
yum list | grep 软件名
这里我们以从中查找lrzsz为例。
lrzsz可以将Windows当中的文件上传到Linux当中也可以将Linux当中的文件下载到Windows当中实现云服务器和本地机器之间进行信息互传。
需要用到的指令
yum list | grep lrzsz 他上面的那一句话意思为 “元数据超过两周没有更新。要安装 yum-cron 吗还是运行yum makecache fast”
这样我们就可以查看我们所关注的lrzsz的相关软件包。
安装软件
指令 sudo yum install 软件名
sudo yum install lrzsz
yum会自动找到都有哪些软件包需要下载这时候我们需要做的就是敲“y”确认安装等待一些时间后就会出现“complete”字样时这时就说明安装完成。
但是我这里已经安装过了他显示的就不会显示 “complete”字样也不需要一直按y 注意事项
1 yum命令需要sudo权限因为安装、更新和删除软件包需要修改系统级别的文件和目录这些操作需要管理员权限。使用sudo可以授权普通用户临时获得管理员权限确保这些系统管理操作的安全性和合规性。
2yum安装软件只能一个装完了再装另一个正在使用yum安装一个软件的过程中如果再尝试用yum安装另外一个软件yum会报错。 如何实现本地机器和云服务器之间的文件互传
既然已经安装了lrzsz那么就顺便展示一下其怎么使用从的可以互传文件
指令 rz -E
通过该指令可选择需要从本地机器上传到云服务器的文件。
当我们打完这个指令时就会跳出这个windows窗口然后我们选择我们要互传的文件就完成了从本机到云服务器的操作了。 指令 sz 文件名 该指令可将云服务器上的文件下载到本地机器的指定文件夹。
当我们按下这个指令的时候同样会跳出一个这样的一个windows的窗口然后选择想要传到的路径即可。 卸载软件
指令 sudo yum remove 软件名
就比如说我们卸载刚才下载的lrzsz那么只需要运行这段指令
sudo yum remove lrzsz
yum就会自动卸载该软件同样还会卸载其各种的依赖关系这时我们只需要敲“y”确认卸载当出现“complete”字样时说明卸载完成。
Linux编辑器 - vim
vim的基本概念
vim在我们做开发的时候主要解决我们编写代码的问题本质上就是一个多模式的文本编辑器。
我们这里主要介绍vim最常用的三种模式命令模式、插入模式、底行模式。1、正常/普通/命令模式Normal mode。 在命令模式下我们可以控制屏幕光标的移动字符、字或行的删除复制粘贴剪贴等操作。2、插入模式Insert mode。 只有在插入模式下才能进行文字输入该模式是我们使用最频繁的编辑模式。3、末行/底行模式Command mode。 在底行模式下我们可以将文件保存或退出也可以进行查找字符串等操作。在底行模式下我们还可以直接输入vim help-modes查看当前vim的所有模式。
其实除此之外还有很多模式这里就只介绍三个最常用的。
vim下各模式的切换
首先我们要进入vim模式要使用如下指令
指令 vim 文件名
vim test.c
进入vim后默认为命令模式普通模式要输入文字需切换到插入模式就可以想在vs下敲代码了。 【命令模式】切换至【插入模式】 1输入「i」在当前光标处进入插入模式。 2输入「a」在当前光标的后一位置进入插入模式。 3输入「o」在当前光标处新起一行进入插入模式。
【命令模式】切换至【底行模式】 1输入「Shift;」即可实际上就是输入「:」。
【插入模式】或【底行模式】切换至【命令模式】 1插入模式或是底行模式切换至命令模式都是直接按一下「Esc」键即可。
vim命令模式各命令汇总【移动光标】 1按「k」光标上移。 2按「j」光标下移。 3按「h」光标左移。 4按「l」光标右移。 5按「$」移动到光标所在行的行尾。 6按「^」移动到光标所在行的行首。 7按「gg」移动到文本开始。 8按「Shiftg」移动到文本末尾。 9按「nShiftg」移动到第n行行首。 10按「nEnter」当前光标向下移动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按「Ctrlr」恢复刚刚的撤销。【大小写切换】 1按「~」完成光标所在位置字符的大小写切换。 2按「n~」完成光标所在位置开始往后的n个字符的大小写切换。【替换】 1按「r」替换光标所在位置的字符。 2按「R」替换光标所到位置的字符直到按下「Esc」键为止。【更改】 1按「cw」将光标所在位置开始到字尾的字符删除并进入插入模式。 2按「cnw」将光标所在位置开始往后的n个字删除并进入插入模式。【翻页】 1按「Ctrlb」上翻一页。 2按「Ctrlf」下翻一页。 3按「Ctrlu」上翻半页。 4按「Ctrld」下翻半页。
vim底行模式各命令汇总 在使用底行模式之前记住先按「Esc」键确定你已经处于命令模式再按「:」即可进入底行模式。
【行号设置】 1「set nu」显示行号。 2「set nonu」取消行号。【保存退出】 1「w」保存文件。 2「q」退出vim如果无法离开vim可在「q」后面跟一个「!」表示强制退出。 3「wq」保存退出。【分屏指令】 1「vs 文件名」实现多文件的编辑。 2「Ctrlww」光标在多屏幕下进行切换。【执行指令】 1「!指令」在不退出vim的情况下可以在指令前面加上「!」就可以执行Linux的指令例如查看目录、编译当前代码等。 这时候就有疑惑了为什么跟我们平时的操作完全不一样用起来包别扭 因为这就是Linux的特点他与Windows的操作系统是要注定不一样的比如说我们在买电脑时其实不光买的是硬件与软件还包括其操作系统等等一些东西。你可能感觉不到我没有为Windows的操作系统付钱啊但是实际上在我们买电脑时这一部分钱就已经算上了。 很明显的就是大部分公司都是使用的Linux这是因为Linux是免费开源的而Windows是要付费的比方说你要开一个互联网公司在选择操作系统的时候如果选择windows那么要为其公司付款好几百万而Linux是免费的你说你选那个肯定是Linux啊。 批量化注释 这里再多填一嘴如何再Linux下进行批量化注释 先进入命令模式下选择多行按下Ctrl v进入可视模式Visual Block Mode然后使用H, J, K, L键或箭头键选择你要注释的多行。进入插入模式选中多行后按下Shift i进入插入模式。批量注释在选中的每一行前面插入注释符号例如//为c语言与c的注释符号。此时你会看到光标在每一行的开始位置。退出插入模式输入完注释符号后按下Esc键退出插入模式所有选中的行前都将自动添加注释符号。 vim的简单配置
【配置文件的位置】 1在目录/etc/下面有个名为vimrc的文件这是系统中公共的配置文件对所有用户都有效。 2在每个用户的主目录/home/xxx下都可以自己建立私有的配置文件命名为“.vimrc”这是该用户私有的配置文件仅对该用户有效。
例如普通用户在自己的主目录下建立了“.vimrc”文件后在文件当中输入set nu指令并保存下一次打开vim的时候就会自动显示行号。
vim的配置比较复杂某些vim配置还需要使用插件建议不要自己一个个去配置。比较简单的方法是直接执行以下指令想在哪个用户下让vim配置生效就在哪个用户下执行该指令不推荐直接在root下执行curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh bash ./install.sh 然后按照提示输入root密码
然后等待安装配置最后手动执行source ~/.bashrc即可。
配置完成后像什么自动补全、行号显示以及自动缩进什么的就都有了就可以像再vs下敲代码了如果跟自己以前使用的习惯不一样也可以自己修改。
只需要执行下面的指令找到配置的文件自己使用刚才的vim知识对应修改即可。
vim ~/.vimrc
Linux编译器 - gcc/g
gcc/g的作用
gcc和g分别是GNUGNU是一个自由软件的项目其旨在创建一个完全自由的操作系统的C和C的编译器gcc和g在执行编译的时候一般有以下四个步骤
1预处理头文件展开、去注释、宏替换、条件编译等等。 2编译C代码翻译成汇编语言。 3汇编汇编代码转为二进制目标代码。 4链接将汇编过程产生的二进制代码进行链接。
gcc/g语法
语法 gcc/g 选项 文件
常用选项 1-E 只进行预处理这个不生成文件你需要把他重定向到一个输出文件里面否则将把预处理后的结果打印到屏幕上。 2-S 编译到汇编语言不进行汇编和链接即只进行预处理和编译。 3-c 编译到目标代码 4-o 将处理结果输出到指定文件该选项后需紧跟输出文件名。 5-static 此选项对生成的文件采用静态链接。 6-g 生成调试信息若不携带该选项则默认生成release版本。 7-shared 此选项将尽量使用动态库生成文件较小。 8-w 不生成任何警告信息。 9Wall 生成所有警告信息。 10-O0/-O1/-O2/-O3 编译器优化选项的四个级别-O0表示没有优化-O1为缺省值-O3优化级别最高。 这里简单说明一下什么是条件编译举一个生活的小例子 你作为一名公司的老总今年创建了一个软件发布了分为社区版免费和专业版收费。 但是你作为老总并且还是一个资深的程序员你就给你手下的员工说我们只需要维护专业版的代码数据就行了然后在在专业版中裁剪出一些功能在放出来进行组装成社区版就行我们只要维护好专业版就行。在这个过程中我们的代码只维护了一个版本-专业版。社区版是通过各种条件裁剪出来的是专业版的子集。这个裁剪的过程就是条件编译把符合条件的裁剪出来。社区版就是被裁剪出来的。 所以说条件编译是在专业版中存在的。 预处理
gcc -E test.c -o test.i
这里的 -E 就是告诉gcc/g从现在开始进行程序的编译将预处理的工作做完就停止下来不要往后走了
预处理功能主要包括头文件展开、去注释、宏替换、条件编译等。预处理指令是以#开头的代码行。-E选项的作用是让gcc/g在预处理结束后停止编译过程。-o选项是指目标文件“xxx.i”文件为已经过预处理的原始程序。 编译
gcc -S test.i -o test.s
这里的 -S 是告诉gcc/g从现在开始进行程序的翻译将编译工作做完就停下来。
在编译过程中GCC/G 首先会检查源代码的规范性确认是否存在语法错误等问题以确定代码的正确性。在没有错误的情况下编译器将源代码翻译成汇编语言。用户可以使用 -S 选项来查看编译后的汇编代码。该选项会停止在编译阶段只生成汇编文件而不继续进行汇编或链接操作。编译器会生成一个以 .s 为后缀的文件表示代码已经被翻译为汇编语言。另外-o 选项用来指定输出文件的名称。如果不指定该选项默认的输出文件名将为 xxx.s其中 xxx 是源文件名去掉扩展名。 汇编
gcc -c test.s -o test.o
这里的 -c 告诉gcc/g从现在开始进行程序的翻译将汇编工作做完就停下来。
汇编阶段是把编译阶段生成的“xxx.s”文件转成目标文件。使用-c选项就可以得到汇编代码转化为“xxx.o”的二进制目标代码了。 链接
gcc test.o -o test// 这里的test就是可执行程序名自己可以根据自己喜好自己设定
在成功完成以上步骤之后就进入了链接阶段。链接的主要任务就是将生成的各个“xxx.o”文件进行链接生成可执行文件。gcc/g不带-E、-S、-c选项时就默认生成预处理、编译、汇编、链接全过程后的文件。若不用-o选项指定生成文件的文件名则默认生成的可执行文件名为a.out。 注意 链接后生成的也是二进制文件。
静态库与动态库
我们最后的一步链接就需要链接动态库或者静态库在规定上一个文件是由你书写头文件对应的头文件提供方法的伤命库文件提供方法的实现你的代码这就形成了一个你的文件。在windows下动态库后缀为 .dll 静态库为 .lib
函数库一般分为静态库和动态库两种
静态库是指编译链接时把库文件的代码全部加入到可执行文件当中因此生成的文件比较大但在运行时也就不再需要库文件了静态库一般以.a为后缀。动态库与之相反在编译链接时并没有把库文件的代码加入到可执行文件当中而是在程序运行时由链接文件加载库这样可以节省系统的开销动态库一般以.so为后缀。
动态库与静态库相对比
动态库因为是共享库有效的节省了资源磁盘空间内存空间网络空间等【优点】动态库一旦缺失导致各个程序都无法运行【缺点】静态库不依赖库程序可以独立运行【优点】体积大比较消耗资源【缺点】 那么看这些知识还是相对于比较繁琐那么下面就举一个很生动的生活小例子来解释一下吧 现在你的身份是一名高一的高中生现就读于好的高中作为大一的你学习压力不大并且你的学习还不错在这个星期6你突然感觉压力好大啊不想学了想出去玩一会但是你的学校地方很偏僻又不知道去哪玩所以你就像你的学长询问了一下附近有没有好玩的地方啊。你的学长告诉你学校从北门出去向东500m有一家网吧只有一家。所以你星期6都会和自己的好朋友同学1/同学2......)就去玩了。就这样每个星期都去完大概过了一个月突然当你去的时候这家网吧被查封了警察问老板你有营业执照么老板说没有我是个黑网吧所以这家网吧就被查封了。 上述中你的身份于别的同学等效到我们的操作系统就是可执行程序 你的学长就是编译器 网吧就是动态库 网吧作为一个开放的场所谁都可以上网所以动态库又是共享库 跑去网吧上网打游戏就是动态链接 网吧被查封导致所有的同学无法去上网就是动态库一旦缺失导致各个程序都无法运行 图中物理作业数学作业......就是可执行程序的各个文件 上网的机器不在自己的宿舍就是有效的节省了资源磁盘空间内存空间网络空间等 恰巧你的学校北门向西走一段路开了一个电脑店你和你的同学都配了一台电脑每一个电脑都需要占用宿舍的一定空间。这样你和你的同学每个星期6又可以自己在宿舍上网了。 这个电脑店就是静态库 给你们配电脑就是静态链接 电脑占用宿舍空间体积大比较消耗资源 上网不用去网吧就是就是不依赖库程序可以独立运行 动态链接 优点省空间磁盘的空间内存的空间bin体积小加载速度快。 缺点依赖动态库程序可移植性较差。静态链接 优点不依赖第三方库程序的可移植性较高。 缺点浪费空间。
gcc和g默认生成的二进制程序是动态链接的我们可以使用file指令进行查看。
指令file 文件名 其次我们还可以使用ldd指令查看动态链接的可执行文件所依赖的库。
指令ldd 文件名 图中的/lib64/libc.so.6就是当前云服务器当中的C标准库。 虽然gcc和g默认采用的是动态链接但如果我们需要使用静态链接带上-static选项即可。
gcc test.c -o test_s -static
但是如果是第一次尝试那么他会报错如下 还拿上面的例子解释我们进行静态链接其实就是去电脑店配好电脑后安装到宿舍里面但是如果我们没有在宿舍装好那肯定是不能上网的这也很好理解。通俗的来讲就是你没电脑怎么上网啊。
用官方的话就是
缺少静态库 CentOS 7 默认安装的是动态链接的 C 库 (glibc)而静态库 (libc.a) 需要单独安装。
你可以检查是否已经安装了静态版本的 C 库。静态库文件通常位于 /usr/lib/ 或 /usr/lib64/ 目录下。如果没有你可以尝试安装 glibc-static 包。
然后对应按y然后看到Complete!字样时表示安装完成。然后再执行上面的操作就可以静态链接了。
这段指令的本质就是改变了优先级使得先使用静态库在混合的库的情况下所有的链接将全变为静态链接
sudo yum install glibc-static
此时生成的可执行文件就是静态链接的了。 我们可以查看源代码相同但链接方式不同而生成的两个可执行程序test和test_s的大小 相差的还是蛮多的。 这也证明了如果直接去网吧上网确实比宿舍上网节省空间动态链接比较节省空间而静态链接比较浪费空间。 除此之外Linux的链接还遵循如下规则 如果无静态库但还是要用-static则是不行会出现报错。无动态态库仅有静态库而且gcc可以找到静态库gcc 会默认调用静态库。其余情况下默认调用动态库。遵循规则就是有动用动无动用静全无报错对于库不一定是纯静态或者动态的一般是存在混合的。 Linux调试器 - gdb
gdb使用须知
程序发布方式 1、debug版本程序本身会被加入更多的调试信息以便于进行调试这个版本是程序员所用的版本文件大一点。 2、release版本不会添加任何调试信息是不可调试的也叫做发行版本文件小一点。
在Linux当中gcc/g默认生成的可执行程序是release版本的是不可被调试的。如果想生成debug版本就需要在使用gcc/g生成可执行程序时加上-g选项。
gcc test.c -o test_g -ggdb命令汇总
【进入gdb】指令 gdb 文件名
【调试】 1「run/r」运行代码启动调试。 2「next/n」逐过程调试。 3「step/s」逐语句调试。 4「until 行号」跳转至指定行。 5「finish」执行完当前正在调用的函数后停下来不能是主函数。 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 变量」将变量加入常显示每次停下来都显示它的值。 7「display 变量」将变量的地址加入常显示。 8「undisplay 编号」取消指定编号变量的常显示。 9「bt」查看各级函数调用及参数。 10「info/i locals」查看当前栈帧当中局部变量的值。
【断点】 1「break/b n」在第n行设置断点。 2「break/b 函数名」在某函数体内第一行设置断点。 3「info breakpoint/b」查看已打断点信息。 4「delete/d 编号」删除指定编号的断点。 5「disable 编号」禁用指定编号的断点。 6「enable 编号」启用指定编号的断点。
【退出gdb】 1「quit/q」退出gdb
Linux项目自动化构建工具 - make/Makefile
make/Makefile的重要性
会不会写Makefile从侧面说明了一个人是否具备完成大型工程的能力。一个工程的源文件不计其数按照其类型、功能、模块分别放在若干个目录当中Makefile定义了一系列的规则来指定哪些文件需要先编译哪些文件需要后编译甚至于进行更复杂的功能操作。Makefile带来的好处就是“自动化编译”一旦写好只需一个make命令整个工程完全自动编译极大的提高了软件开发的效率。mak是一个命令工具是一个解释Makefile当中指令的命令工具一般来说大多数的IDE都有这个命令例如Delphi的makeVisualC的nmakeLinux下GNU的make。可见Makefile都成为了一种在工程方面的编译方法。make是一条命令Makefile也可以使用makefile效果一样是一个文件两个搭配使用完成项目自动化构建。
依赖关系和依赖方法
在使用make/Makefile前我们首先应该理解各个文件之间的依赖关系以及它们之间的依赖方法。
依赖关系在我们日常生活中你与你的父亲就是存在依赖关系。比方说你作为一个大学生每个月初都会给你的爸爸打电话要生活费。你打过去电话叫一声爸你把就立马反应过来是你但是你的舍友给你爸打电话叫一声爸你爸还会以为骚扰电话会直接挂断。如果哪一个月你爸跟你说这个月的家里面有些情况没有太多钱了就少给你点吧按以前的一半吧。这个过程你就依赖于你爸有依赖关系。而你的同学不可以依赖于你爸就没有依赖关系。那一个月家里面有情况影响了你爸从而导致影响了你这就是依赖关系所产生的影响。
那么把这个概念转化为Linux下就为文件A的变更会影响到文件B那么就称文件B依赖于文件A。
拿前面的编译的内容举例我们生成test.i文件就是依赖于test.c文件所生成的。如果把test.c修改了那么test.i也会产生影响。
依赖方法 如果文件B依赖于文件A那么通过文件A得到文件B的方法就是文件B依赖于文件A的依赖方法。也就是上面举例的你可以通过打电话找到你爸。
那么把这个概念转化为Linux下的编译部分就为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指令对多个源文件进行编译进而生成可执行程序。
gcc -o test test.c main.c main.h这里的main.h可加可不加尽量不要加因为编译器通过源文件的内容可以知道所需的头文件名字而通过头文件的包含方式“尖括号”包含和“双引号”包含编译器可以知道应该从何处去寻找所需头文件。这个程序我是实现了打印56的结果没有加换行。 通常在多文件编译时不会直接从源文件生成最终的可执行文件而是会将每个源文件分别编译成目标文件*.o 文件然后再通过链接gcc将这些目标文件链接成最终的可执行程序。 原因
若是直接使用源文件生成可执行程序那么其中一个源文件进行了修改再生成可执行程序的时候就需要将所以的源文件重新进行编译链接。而若是先用每个源文件各自生成自己的二进制文件那么其中一个源文件进行了修改就只需重新编译生成该源文件的二进制文件然后再将这些二进制文件通过链接生成可执行程序即可。
随着源文件数量的增加每次重新生成可执行程序时所需的 gcc 指令长度和数量也会随之增加。此时使用 make 工具和 Makefile 文件能够显著减少我们的工作量。
步骤一 在源文件所在目录下创建一个名为Makefile/makefile的文件。 步骤二 编写Makefile文件。
Makefile文件最简单的编写格式是先写出文件的依赖关系然后写出这些文件之间的依赖方法依次写下去。但也要记清楚他的独特书写方式。 编写完毕Makefile文件后保存退出然后在命令行当中执行make指令便可以生成可执行程序以及该过程产生的中间产物。 Makefile文件的简写方式
$表示依赖关系中的目标文件冒号左侧。$^表示依赖关系中的依赖文件列表冒号右侧全部。 例如以上Makefile文件可以简写为 make原理
make会在当前目录下找名字为“Makefile”或“makefile”的文件。如果找到它会找文件当中的第一个目标文件在上面的例子中它会找到test这个文件并把这个文件作为最终的目标文件。如果test文件不存在或是test所依赖的后面的test.o文件和main.o文件的文件修改时间比mytest文件新那么它就会执行后面的依赖方法来生成mytest文件。如果test所依赖的test.o文件不存在那么make会在Makefile文件中寻找目标为test.o文件的依赖关系如果找到则再根据其依赖方法生成test.o文件类似于堆栈的过程。当然你的test.c文件和main.c文件是存在的于是make会生成test.o文件和main.o文件然后再用test.o文件和main.o文件生成最终的mytest文件。make会一层又一层地去找文件的依赖关系直到最终编译出第一个目标文件。在寻找的过程中如果出现错误例如最后被依赖的文件找不到那么make就会直接退出并报错。
项目清理
在我们每次重新生成可执行程序前都应该将上一次生成可执行程序时生成的一系列文件进行清理但是如果我们每次都手动执行一系列指令进行清理工作的话未免有些麻烦因为每次清理时执行的都是相同的清理指令这时我们可以将项目清理的指令也加入到Makefile文件当中。 像clean这种没有被第一个目标文件直接或间接关联那么它后面所定义的命令将不会被自动执行但我们可以显示要make执行。 注 一般将这种clean的目标文件设置为伪目标用.PHONY修饰伪目标的特性是总是被执行。 如果我们把 clean 放在 Makefile 的第一个位置并且 Makefile 的默认目标是 clean那么在调用 make 指令时就会自动执行 clean 目标而不需要显式地使用 make clean。在 Makefile 中第一个目标 是默认目标。当你执行 make 命令时默认会尝试构建第一个目标。如果你把 clean 作为第一个目标make 就会自动执行 clean 的规则而不需要明确指定 make clean。 就不如说我们这样定义Makefile clean: rm -f *.o testtest: test.o main.ogcc -o $ $^test.o: test.cgcc -c $^ -o $main.o: main.cgcc -c $^ -o $在这个 Makefile 中 默认目标 是 clean因为它是 Makefile 中的第一个目标。当你运行 make 时它会自动执行 clean 规则删除所有的 .o 文件和 test 可执行文件。你不需要显式运行 make clean因为 clean 是默认目标。