Makefile总述
一、Makefile里面有什么
Makefile主要包含了五个东西:显示规则、隐晦规则、变量定义、文件指示和注释。
显示规则:明显指出要生成的文件,文件的依赖文件,生成的命令
隐晦规则:make具有自动推导功能,隐晦规则可以比较粗糙地简略书写Makefile
变量定义:如一中的objects
文件指示:一个Makefile中引用另一个Makefile;根据某些情况指定Makefile中的有效部分;定义一个多行的命定
注释:‘#’,文件中使用该符号可以利用转义符号‘/#’
注:Makefile中的命令,必须以Tab键开始。
二、Makefile的文件名
默认情况下,make命令会在当前目录下按顺序寻找“GNUmakefile”、“makefile”、“Makefile”文件。最好使用“Makefile”。
还可使用别的文件名来书写Makefile,比如:“Make。Linux”,“Make.Solaris”,“Make.AIX”等。如果要制定特定的Makefile,可以使用make的“-f”和“--file”参数,如:make -f Make.Linux或make --file Make.AIX。
三、引用其他的Makefile
在Makefile中使用include关键字可以把别的Makefile包含进来,被包含的文件会原模原样的放在当前文件的包含位置。
include语法是:
include<filename> #filename可以是当前操作系统的Shell的文件模式,可以包含路径和通配符
在include前面可以有一些空字符,但是绝不能是Tab键开始。include和<filename>可以用一个或多个空格隔开。
例子,现有这样几个Makefile:a.mk,b.mk,c.mk,还有一个文件foo.make,变量¥(bar)=e.mk f.mk,那么
include foo.make *.mk $(bar) ====》》》 等价于:include foo.make a.mk b.mk c.mk e.mk f.mk
make命令开始时,会找寻include所指出的其他Makefile,并把其内容安置在当前的位置。如果文件没有指定绝对路径或是相对路径的话,make会在当前目录下首先寻找,如果当前目录下没有找到,那么make还会在以下几个目录找:
1、如果make执行时,有“-I”或“--include-dir”参数,那么make就会在这个参数所指定的目录下寻找
2、如果目录<prefix>/include(一般是:/usr/local/bin或/usr/include)存在的话,make也会去找
如果文件没有找到的话,make会生成一条警告信息,但不会马上出现致命错误,他会继续载入其他文件,一旦完成makefile的读取,make会再重试这些没有找到或是不能读取的文件,如果还是不行,make才会出现一条致命信息。若想make不理会那些无法读取的文件继续执行,可在include前加‘-’。如:-include<filename>。和其他版本make兼容的相关命令是sinclude,作用一样。
四、环境变量MAKEFILES
(我也没看懂到底是个啥,就记住了最好不要用,如果出错可以检查是否用了)
如果当前环境中定义了环境变量MAKEFILES,那么,make会把这个变量中的值做一个类似include的动作。这个变量中的值是其他的Makefile,用空格分隔。只是他与include不同的是,从这个环境变量中引入的Makefile的目标不会起作用,如果环境变量中定义的文件发现错误,make也不理会。
建议不要使用环境变量,因为一旦定义,当时用make时,所有的Makefile都会受到影响。
五、make的工作方式
GUN的make工作执行步骤如下:
1、读入所有的Makefile
2、读入被include的其他Makefile
3、初始化文件中的变量
4、推导隐晦规则,分析所有规则
5、为所有目标文件创建依赖关系链
6、根据依赖关系,决定哪些目标要重新生成。
7、执行生成命令。
567解释了先生成所有的依赖关系,再执行命令,很好的完成了哪些需要重新编译
1-5:第一个阶段,6-7:第二个阶段。第一阶段中,如果定义的变量被使用了,那么make会把其展开在使用的位置,但make并不会完全马上展开,make使用的是拖延战术。如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。(也没懂)