本文目录
背景简介
细说关于make命令和makefile文件:
使用方法
为什么执行的指令是make和make clean呢?
gcc如何判断文件是否需要重新执行?
背景简介
- 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefifile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
- makefifile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
- make是一个命令工具,是一个解释makefifile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefifile都成为了一种在工程方面的编译方法。
- make是一条命令,makefifile是一个文件,两个搭配使用,完成项目自动化构建
细说关于make命令和makefile文件:
- makefile文件中,保存了编译器和链接器的参数选项,并且描述了所有源文件之间的关系。make程序会读取makefile文件中的数据,然后根据规则调用编译器,汇编器,链接器产生最后的输出。
- Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释:
- 显式规则说明了,如何生成一个或多个目标文件
- 在makefile中可以定义变量,当makefile被执行时,其中的变量都会被扩展到相应的引用位置上,通常使用 $(var) 表示引用变量
- 文件指示。包含在一个makefile中引用另一个makefile,类似C语言中的include;
- 注释,makefile中可以使用 # 在行首表示行注释
- make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写makefile,比如源文件与目标文件之间的时间关系判断之类
- 默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件
- make的执行规则是,只生成所有目标对象中的第一个,当然make会根据语法规则,递归生成第一个目标对象的所有依赖对象后再回头生成第一个目标对象,生成后退出。
使用方法
make :一个命令 makefile:一个文件(需在当前的源代码路径下) 注:Makefile/makefile 文件均可
makefile 是一个围绕依赖关系和依赖方法的一个自动化编译的工具
形成:正确关系+正确方法
编写规则:第一行是依赖关系(目标文件对应的依赖关系文件列表可以为空),第二行为依赖方法(注意必须Tab一下编写)
依赖关系:
上面的输出文件myfile,它依赖myfile.c
clean依赖关系的文件列表为空
依赖方法:
gcc myfile.c -o myfilerm -f myfile
注:
- 像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
- makefile中使用 .PHONY 来声明伪对象
- .PHONY:总是被执行的(冒号后面的命令总是被执行的)
- makefile中的伪对象表示对象名称并不代表真正的文件名,与实际存在的同名文件没有相互关系,因此伪对象不管同名目标文件是否存在都会执行对应的生成指令。伪对象的作用有两个,1. 使目标对象无论如何都要重新生成。2. 并不生成目标文件,而是为了执行一些指令。
- make 默认执行第一组依赖关系
为什么执行的指令是make和make clean呢?
因为单独使用make: 默认执行第一组依赖关系
如果后面还有其他依赖关系:使用则需要make + 目标文件执行,如:make myfile / make clean
gcc如何判断文件是否需要重新执行?
如何判断需要重新执行 : 通过对比时间信息来进行
make在执行makefile规则中,根据语法规则,会分析目标对象与依赖对象的时间信息,判断是否在上一次生成后,源文件发生了修改,若发生了修改才需要重新生成
通过stat命令可以显示文件的状态信息:Modify代表文件内容被修改的时间,Change代表文件属性被修改的时间,Access代表最后一次访问文件的时间
我们可以看到,编译后的myfile文件(可执行程序)Modify时间比myfile.c(源文件)Modify时间更晚,gcc通过识别比较源文件和可执行程序Modify时间判断是否需要重新编译。如果可执行程序显示时间更早,说明源文件被修改了,那就需要重新编译,如果源文件显示时间更早,说明可执行程序被修改过,不需要重新编译。
本节完