汽车企业网站开发方案,河南郑州天气预报15天,wordpress字体旋转,wordpress写插件个人主页 #xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. 认识make/Makefile3. 了解make/Makefile原理3.1 依赖关系和依赖方法3.2 make检测的顺序3.3 PHONY:XXX 4. makefile内置符号 1. 前言
在上一篇中已经了解了【Linux】编译器-gcc/g使用#xff0c;这次来一起… 个人主页 zxctscl 如有转载请先通知 文章目录 1. 前言2. 认识make/Makefile3. 了解make/Makefile原理3.1 依赖关系和依赖方法3.2 make检测的顺序3.3 PHONY:XXX 4. makefile内置符号 1. 前言
在上一篇中已经了解了【Linux】编译器-gcc/g使用这次来一起看看make/Makefile。
2. 认识make/Makefile
make是一个命令 makefile是一个文件。
先touch一个makefile/Makefilem大小写都可以文件 然后进入makefile写一段代码 未来形成的可执行程序是mytest依赖的是test.c。就是将test.c编译形成mytest的可执行程序。 直接make编译一下 因为版本比较低这里提示要加上-stdc99。重新打开makefile加上就行
此时在重新make一下就有了 会自动形成我们要的可执行程序mytest 如果想要清理编译产生的临时文件怎么办 再次打开makefile
退出后直接用命令清理一下
make clean发现mytest已经没有了 makefile文件中保存了编译器和链接器的参数选项并且描述了所有源文件之间的关系。 make程序会读取makefile文件中的数据然后根据规则调用编译器汇编器链接器产生最后的输出。 Makefile里主要包含了五个东西显式规则、隐晦规则、变量定义、文件指示和注释。 显式规则说明了如何生成一个或多个目标文件。 make有自动推导的功能所以隐晦的规则可以让我们比较粗糙地简略地书写makefile比如源文件与目标文件之间的时间关系判断之类 在makefile中可以定义变量当makefile被执行时其中的变量都会被扩展到相应的引用位置上通常使用 $(var) 表示引用变量文件指示。包含在一个makefile中引用另一个makefile类似C语言中的include 注释makefile中可以使用 # 在行首表示行注释 默认的情况下make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件
3. 了解make/Makefile原理
打开Makefile来看看前面两行 写好Makefile后当我们实际是在运行make时候对应的程序就会在当前程序找makefile然后读取makefile里面的内容根据依赖关系知道test.c形成mytest这样的可执行程序根据gcc写的依赖方法来执行。
make会根据makefile的内容完成编译或者清理工作。
3.1 依赖关系和依赖方法
怎么理解依赖关系和依赖方法呢
举个例子在现实生活中求人办事就先得和他们产生某种关系然后才会有后面的方法。就像小明没有生活费了向他父亲打电话就说一句我是你儿子。这个就表明了依赖关系。表明了依赖关系然后小明想要做什么所以小明重新打电话说我是你儿子没钱了打点钱。就有了依赖方法。 计算机要形成某种可执行程序就得先表明依赖关系然后怎么具体形成可执行程序这就要有具体依赖方法。
依赖关系和依赖方法是完成一件事情的必然要素并非makefile特有的。 这里clean:是一种特殊的依赖关系这个clean不依赖任何一个文件是一种特殊情况。 所以说依赖文件列表可以为空。
3.2 make检测的顺序
在形成可执行程序的时候直接make就可以直接形成mytest而不是执行clean? 要执行clean,就必须这样写make clean
也可以用make mytest这样去运行 makefile它的运行推导规则是默认从上到下对makefile文件进行扫描默认形成第一个目标文件。也就是只有make的时候默认形成第一个目标文件。
如果把clean放在前面那么默认先执行的就是clean 发现直接make的时候先执行的clean
默认将执行的可执行程序放在前面这样make的时候就能直接形成了。 所以make检测的顺序是从上往下的。
3.3 PHONY:XXX
当我们在程序里面不加上
来make一下后在make一下发现就不行了 在程序不被修改时make后默认就不会在形成新的可执行程序它认为没有必要。 如果想要makefile里面的操作总是被执行不要因为是最新的就拦截就加上.PHONY:mytest make多少次都会执行,没有拦截。
.PHONY:XXXXXX对应的方法总是要被执行。
一般可执行程序不需要.PHONY:修饰但是我们总是希望clean重新清理。 默认将clean用.PHONY:修饰 要然清理工作总是被执行。 为什么makefile对最新的可执行程序默认不重新形成呢 如果在一个项目里面存在上千个源文件每次改代码时候可能就修改一小部分。做了改动之后如果每一次都把所以的源文件重新编译一遍就会带来效率的延缓。还有可能出现在没有修改情况下一编译就重新执行上千个文件在编译的时候又得重新编译又得花费很长时间。既然形成的可执行程序都是新的那么就不需要再重新编译。 就是为了提高编译效率。
那么是怎么做到不重新执行的呢换句话说makefile怎么知道我的程序需要被编译呢
这里有一个Modify文件的最新修改时间 源代码和可执行程序最近一次形成或者修改的时间一定是不一样的。 每一次都是先写源代码再形成可执行程序。 最终要判断程序是否被编译只要对比可执行文件最近修改的时间和源文件最近修改的时间谁更新。 可执行程序最新就不需要再编了源文件最新就重新编译一下。
这里源文件没有更新就不能再编译 来修改一下test.c的Modify时间
touch test.cmake一下就又可以编了
4. makefile内置符号 $:相当于取内容。 ^:代表整个依赖文件列表就是这里的code.c 代表目标文件就是这里的code.exe
在编译的时候makefile会自动进行符号替换把替换为目标文件^替换为code.c
make之后执行一下code.exe:
在把它清理掉 把makefile如果要把它写全就是这样的 实际上编译器可以直接一步到位。 上面有4组依赖关系就有依赖方法 1 code.exe:code.o2 gcc code.o -o code.exe -stdc993 code.o:code.s4 gcc -c code.s -o code.o -stdc995 code.s:code.i6 gcc -S code.i -o code.s -stdc997 code.i:code.c8 gcc -E code.c -o code.i -stdc99 在make后在makefile里面写的代码重新编译了编译后依此形成了临时文件并且形成了最终的可执行程序: 运行一下
重新进入makefile 1 code.exe:code.o2 gcc code.o -o code.exe -stdc993 code.o:code.s4 gcc -c code.s -o code.o -stdc995 code.s:code.i6 gcc -S code.i -o code.s -stdc997 code.i:code.c8 gcc -E code.c -o code.i -stdc999 .PHONY:clean10 clean:11 rm -f code.i code.s code.o code.exe此时code.i code.o code.s code.exe都被清理了 发现执行的顺序和makefile里面代码顺序是相反的。 当make拿到makefile文件时候,从上往下扫描先看到的文件是code.exe先识别的依赖关系是code.exe:code.o,但是发现code.o并不存在所以 gcc code.o -o code.exe -stdc99是不执行的。 然后继续找下一组依赖关系code.o:code.s发现code.s并不存在所以不执行这个依赖方法。 一直这样找直到code.i:code.c这个code.c是存在的那么就会执行这一组依赖关系的依赖方法 gcc -E code.c -o code.i -stdc99。那么就形成了code.i。code.i形成了再回到code.s:code.i执行他的依赖方法gcc -S code.i -o code.s -stdc99。一直像这样直到形成code.exe。
makefile/make 会自动根据文件中的依赖关系进行自动推导帮助我们执行所有相关的依赖方法。
这些依赖关系就像栈一样出栈执行方法
如果注释调最后一组依赖关系 就会出现没有规则去制作code.icode.i不存在那么code.s也就不存在。
如果乱序排这些依赖关系 能正常执行
那么如果让第一个依赖关系放在后面呢 此时make就不能执行 因为makefile必须把最重要的文件放在前面总的有个开头。一定要保证最终实现的目标文件是第一个。
那么之后我们写makefile就要这样写吗 其实没有必要这样写。直接这样写就行 1 bincode.exe2 srccode.c34 $(bin):$(src)5 gcc -o $ $^ -stdc996 .PHONY:clean7 clean:8 rm -f $(bin)这样也是可以执行的 这里定义的变量就相当于宏。要改形成的可执行程序就只改前面这两行的文件名就行。 举个例子 重新make一下 如果不想在执行命令的时候出现提示出像下面这样的命令的内容 不想显示出这些命令那么就在这些命令前面加上: 此时发现已经不显示了
一般我们所使用不仅仅只有一个依赖方法可以继续往后跟: 有问题请指出大家一起进步