嵌入式开发---Makefile编写规则
一、Makefile里面包括什么:
1.显式规则
2.隐晦规则
3.变量的定义
4.文件指示
5.注释
Makefile规则:
target......:prerequisites......
command
target也就是一个目标文件,可以使Object file,也可以是一个执行文件,或者是一个标签。(Makefile中的第一个目标文件被当做是最终的目标文件。)
prerequisites是生成目标文件的依赖文件。
command是Make需要执行的命令。
隐晦规则:Makefike的自动推导功能,隐晦规则可以让我们粗糙的简略的书写Makefile,这是由make所支持。
变量的定义:Makefile中定义的一系列变量,一般都是字符串,类似于C语言中的宏,Makefile执行时,变量的值会进行扩展。
文件指示:其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另外一个是根据某些情况指定Makefile中的有效部分,就像C语言中预编译的#if一样;第三点是定义一个多行的命令。
注释:#开头进行注释。
二、伪目标
clean:
rm *.o temp
伪目标不是文件,所以make无法生成它的依赖关系和决定它是否要执行。我们只有通过显式的指明这个目标才能让其生效。
如下:
.PHONY:clean
执行clean命令时接 make clean就可以。
整个过程可以写成以下形式:
.PHONY:clean
clean:
rm *.o temp
三、Makefile的执行过程
1.依次读取变量“MAKEFILES”定义的makefile文件列表;
2.读取工作目录下的makefile文件(根据命名的查找顺序“GNU makefile”“makefile”“Makefile”,首先找到哪个就执行哪个。);
3.依次读取工作目录“makefile”文件中使用的指示符“include”包含的文件;
4.查找重建所有已经读取的makefile文件的规则,如果存在一个目标是当前读取的某一个makefile文件,则执行规则重建此makefile文件,完成以后从第一部开始执行;
5.初始化变量值并展开那些需要立即展开的变量和函数并根据预设条件确定执行分支;
6.根据“终极目标”以及其他的目标依赖关系建立依赖关系链表。
7.执行除“终极目标”以及所有目标的规则(规则中如果依赖文件中任一个文件的时间戳比目标文件新,则使用规则所定义的命令重建目标文件。)
8.执行终极目标所在规则。
四、Makefile常见的自动化变量
$* 不包括扩展名的目标文件名称
$+ 所有的依赖文件以空格分开,并以出现的先后顺序,可能包含重复的依赖文件
$< 第一个依赖文件的名称
$? 所有时间戳比目标文件晚的依赖文件,并以空额分开
$@ 目标文件的完整名称
$^ 所有不重复的依赖文件,以空格分开
$% 如果目标文件归档成员,则该变量表示的目标的归档成员名称
五、make的命令行选项
-C dir 读入指定目录下的Makefile
-f file 读入当前目录下file文件作为makefile
-i 忽略所有命令执行错误
-I dir 指定被包含的Makefile所在目录
-n 只打印要执行的命令,但不执行这个命令
-p 显示make变量数据库和隐含规则
-s 在执行命令是时不显示命令
-w 如果make在执行过程中改变目录,则打印当前的目录名。
六、Makefile中wildcard的用法
在Makefile规则中,通配符会被自动展开。但在变量定义和函数引用时,通配符将失效。这种情况如果需要通配符有效,就需要使用函数“wildcard”,它的用法是$(wildcard PATTERN...),在Makefile中它将被展开为已经存在的,使用空格分开的,匹配此模式的所有文件。
一般我们可以用$(wildcard *.c)来获取工作目录下所有c文件列表。
wildcard:扩展通配符
notdir:去除路径
patsubst:替换通配符
七、Makefile中文件搜寻
在一些大的工程中,有大量的源文件,我们通常的做法是吧这许多的源文件进行分类,并存放在不同的目录中。所以,当make需要去找寻文件的依赖关系时,你可以在文件前加路径,但最好的方法是把一个路径告诉make,让make自动去寻找。
Makefilewe文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个变量,make只会在当前目录中去寻找依赖文件和目标文件。如果定义了这个变量,那么make就会在当前目录中找不到的情况下到所指定的目录下去寻找文件名。
VPATH = src:.../headers
上面的定义指定了两个目录“src”和“../headers”,make会按照这个顺序进行搜索,目录由“冒号”分隔(当然,当前目录永远是最高优先搜索的地方)
另一个设置文件搜索路径的方法是使用makefile的“vpath”关键字,(注意,它是全小写),这不是变量。这是一个make的关键字。这和上面提到的那个VPATH变量很类似,但是它更为灵活。它可以指定不同的文件在不同的搜索路径中,这是一个很灵活的功能。
它的使用方法由三种:
vpath <pattern><direction>为符合模式的文件指定指定搜索目录direction
vpath <pattern>清楚符合模式<pattern>的文件的搜索目录
vpath 清除所有已被设置好的文件搜索目录
vpath使用方法中的<pattern>需要包含"%"字符,“%”字符的意思是匹配零或是若干字符,例如“%h”表示所有以"h"结尾的文件。
<pattern>指定了要搜索的文件级,而<direction>则指定了文件集的搜索目录。
注意点:在Makefile中使用shell命令必须加shell,例如$(shell pwd),不加的话是空值。