实在是太多太长了,分。
Makefile关系到整个工程的编译规则。规定了一些列的规则,来指定哪些文件需要先编译,那些文件需要后编译,那些文件需要重新编译。
为了完成对工程文件的编译,并生成执行文件,可以这样编译这些源文件。
gcc xxx.c ccc.c cccc.c -o main
但这样效率低下,修改了某个就需要全部重新编。
给每个文件编译,再拿这些编译好的编译就会快很多,但这样又容易出错。
需要一个能够按照一定规则对源文件编译的文件,就是Makefile文件。
编写一个Makefile的文件并与源代码放在同一个目录下。
目标...:条件集合...
命令1
命令2
注:行首的空白不能用空白格,必须是tab
对于Makefile中的每个以Tab开头的命令,make会创建一个Shell进程去执行
clean是用来清除make执行过程中产生的临时文件。当使用make命令时,clean下的命令不会被执行,需要以make clean方式单独执行。
clean:
rm *.o
rm xxx
make是如何工作的
Makefile中使用变量
为了Makefile的易维护性,Makefile可以使用变量
objects=main.o xxx.o xxxx.o
main:$(objects)
gcc -o main$(object)
...
让Makefile自动推导
只要make看到一个.o文件就会自动把.c文件加到依赖关系中
清空目标文件的规则
clean要放在文件的最后
.PHONY表示clean是一个"伪目标",可以在rm命令前加一个减号(也许某些文件会出问题,但不管,继续做后面的事情)
makefile内容:
主要包含了5个内容:显式规则、隐式规则、变量定义、文件指示和注释
makefile的文件名
默认情况下,make命令会在当前目下按顺序寻找名为GUNmakefile、makefile、Makefile的文件。最好使用Makefile文件名,最好不要使用GUNmakefile文件名,这个文件是GUN的make识别的。
如果要指定特定的Makefile,可以使用make的-f或--file参数。
包含其他的makefile文件
关键字是include
include指示符告诉make暂停读取当前的Makefile,赚取读取include指定的一个或多个文件,完成后再返回继续当前Makefile的读取
include XXXXX
XXXXX事故shell所支持的文件名(可以使用通配符)
指示符include所在的行可以一个或者多个空格(make程序在处理时将忽略这些空格)开始,不能以Tab字符开始。使用指示符包含进来的Makefile中,如果存在变量或者函数的引用,他们将会在包含他们的Makefile中展开。
make指示符有以下场合
如果include指示符指定的文件不是以斜线开始(绝对路径),且当前目录下也不存在此文件,make将根据文件名试图在以下几个目录下查找:首先,查找使用命令行选项-l或者--include-dir指定的目录,如果找到指定的文件,则使用这个文件;否则依次搜索(如果存在)/usr/gun/include、/usr/include
当在这些目录都没有找到include指定的文件时,马克将会提示一个包含文件未找到的警告提示,但不会立刻推出,而是继续处理Makefile的内容。当完成读取所有的Makefile文件后,make将试图使用规则来创建通过指示符include指定的但未找到的文件,当不能创建它时,make将提示致命错误并推出。
可以使用-include来代替include,忽略由于文件不存在或者无法创建时的错误提示。
为了和其他的make程序进行兼容,也可以使用sinclude来到代替-include(GUN所支持的方式)
变量MAKEFILES
如果当前环境定义了一个MAKEFILES的环境变量,make执行时就会首先将此变量的值作为需要读入的Makefile文件,并且多个文件之间使用空格分开。
区别:
环境变量MAKEFILES主要用在make的递归调用过程中的通信。
推荐的做法是在需要包含其他Makefile文件时使用指示符include来实现。
变量MAKEFILE_LIST
make程序在读取多个Makefile文件时,在对这些文件进行解析执行之前,make读取的文件名时会被自动地追加到变量MAKEFILE_LIST的定义域中。
例:
name1:=$(word$(words$(MAKEFILE_LIST)),$(MAKEFILE_LIST))
include inc.mk
name2:=$(word$(words$(MAKEFILE_LIST)),$(MAKEFILE_LIST))
all:
@echo name1=$(name1)
@echo name2=$(name2)
执行make,结果如下:
name1=Makefile
name2=inc.mk
words返回单词个数
word返回列表中的第i个单词
整体函数的功能时返回MAKRFILE_LIST中最后一个单词
其他特殊变量
GUN make支持一个特殊的变量,且不能通过任何途径给它赋值。此变量展开以后是一个特定的值。这个重要的特殊的变量是.VARIABLES。他被展开以后是此引用点之前Makefile文件中所定义的所有全局变量列表。包括空变量和make的内嵌变量,但不包括目标指定的变量,目标指定变量只在特定目标的上下文有效。
Makefile文件的重建
Makefile可又其他文件生成。如果Makefile由其他文件重建,那么在make开始解析Makefile时,需要读取的是更新后的Makefile。
略
重载另外一个Makefile
某些情况下,会存在两个比较类似于Makefile文件,其中一个需要使用另外一个文件中所定义的变量和规则,可以使用include来包含另一个文件。如果两个文件中存在相同目标,而其描述规则中使用了不同的命名,这是不允许的。遇到这种情况不能使用include来解决。GUN make提供了另一种途径。
在需要包含的Makefile文件中那个,可以使用一个称之为所有匹配模式的规则来描述在A中没有定义的目标,make将会在给定的Makefile文件中寻找没有在当前Makefile中给出的目标更新规则。
略
make如何解析Makefile文件
分为两个阶段
第一阶段:读取所有Makefile文件,内建所有变量,明确规则和隐含规则,并建立所有目标与依赖之间的依赖关系结构链表
第二阶段:根据第一阶段已经建立的依赖关系结构链表决定哪些目标需要更新,并使用对应的规则来重建这些目标。
总结
执行过程: