Makefile入门知识总结五—基本语法

导读:本篇文章讲解 Makefile入门知识总结五—基本语法,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

本章节主要是介绍makefile的基本的语法,章节目录如下:

目录

五、基本语法

5.1、makefile文件的命名

5.2、变量的使用

5.3、make的自动推导

5.4、清空目标文件

5.5、makefile的引用

5.6、换行符和通配符的使用

5.6.1、换行符的使用

5.6.2、通配符的使用

5.7、文件搜索

5.8、伪目标

5.9、多目标

5.10、命令的编写

5.10.1、显示命令

5.10.2、命令执行

5.10.3、忽略出错

5.10.4、定义命令包


五、基本语法

5.1、makefile文件的命名

       一般地,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、 “makefile”、“Makefile”的文件,找到了解释这个文件,但是最好不使用“GNUmakefile”, 这个文件是GNU的make识别的。有另外一些make只对全小写的“makefile”文件名敏感,但是基本上来说, 大多数的make都支持“makefile”和“Makefile”这两种默认文件名。

       此外,你可以使用别的文件名来书写Makefile,比如:“Make.demo”,如果要指定特定的Makefile,你可以使用make的 -f 和 –file 参数, 如: make -f Make.demo 或 make –file Make.demo 。

5.2、变量的使用

cc := gcc

test : main.o demo.o helloword.o

       cc -o test main.o demo.o helloword.o

       在上述的例子中.o文件的字符串被重复利用了,为了使makefile更为简洁且易维护,在此引入变量的应用。Makefile的变量实质上就是一个字符串,可以理解成为C语言中的宏。以上面的makefile为例,我们可以将其改写为如下形式:

cc := gcc

objects: main.o demo.o helloword.o


test : $( objects)

       cc -o test $( objects)
main.o : main.c common.h

       cc -o main.c
demo.o : demo.c demo.h

       cc -o demo.c
helloword.o : helloword.c helloword.h

       cc -o helloword.c

clean:

       rm test  $( objects)

       在该实例中我们定义了一个名为“objects”的变量,并将“main.o demo.o helloword.o”赋值给了该变量。如此一来makefile的可维护性就提升了,在有新的.o文件加入时只需要修改“objects”变量即可。关于变量的使用还有很多内容在接下来的第七章节中将进行详细的叙述。

 

5.3、make的自动推导

       Make工具可以根据.o文件推导出其的依赖关系,和其后面的命令。例如:make编译过程中找到一个demo.o文件,那么make就会推导出其的依赖文件是demo.c,并且它的生成命令是“cc -o demo.c”。则之前的makefile文件又可以进行改写了:

cc := gcc

objects: main.o demo.o helloword.o


test : $( objects)

       cc -o test $( objects)
main.o : common.h
demo.o : demo.h
helloword.o : helloword.h

clean:

       rm test  $( objects)

       在本次改写中,利用make工具能够自动推导的功能进行了makefile的简化,这种自动推导的能力就是make的“隐含规则”。

5.4、清空目标文件

       每个工程编译的过程中往往会生成很多中间文件,制定一个清空目标文件的规则不仅能够使工程能够更为方便的二次编译,此外也可以保持工程目录的整洁。在清空目标文件的过程中,我们使用到了“rm”命令,不过在windows中并没有原生地支持该命令,而且win提供的“del”命名也不能很好地满足需求,所以可以选择安装“git bash”来支持“rm”命令。如下所示:

clean:

       rm test  $( objects)

 

5.5、makefile的引用

       类似于C编程中的“#include”,makefile中也可以使用“include”来包含在编写中所涉及的依赖的makefile文件。其基本语法如下:

include <filename>

       和C编程一样,如果该文件没有指定路径的话,make会在文件的当前目录下遍历该文件,如果在该目录中没有找到的话,make还会在以下目录进行寻找:

1)如果make执行时,有 -I 或 –include-dir 参数,那么make就会在这个参数所指定的目 录下去寻找。

2)如果目录 <prefix>/include (一般是: /usr/local/bin 或 /usr/include )存在的话,make也会去找,PS:这个路径一般是对于Linux系统而言的。

       使用include也可以引用变量(该变量用于makefile文件的定义,如下实例所示),和上述方法一样,添加变量名即可。

demo =  a.mk b.mk c.mk

include $(demo)

the same as:

include a.mk b.mk c.mk

 

5.6、换行符和通配符的使用

5.6.1、换行符的使用

在编写makefile文件时,如果命令过长可以使用反斜杠“\”作为换行符,makefile对于一行上有多少个字符并没有限制。

5.6.2、通配符的使用

       在makefile中支持的通配符有三个,分别是“*”“?”“~”。

1)“~”通常用于文件路径目录的表示,一般表示为当前的用户目录,windows下由于没有用户的宿主目录,所以该目录的话视环境变量“HOME”而定。

2)“*”通常表示为一系列相同属性的文件,如:*.c,表示为所有以c为后缀的文件。

3)“?”通常用于自动化变量的表示,如:$?。

 

5.7、文件搜索

       在一些较大的工程中,源文件通常是根据功能属性以及应用的层次进行分类存放于不同的文件目录中,在make需要寻找文件的依赖文件时,我们可以给文件添加路径,此外可以通过使用VPATH变量,为make提供寻找文件的路径。如下实例所示:

VPATH = common:../demo

在上述的实例中我们指定了“common”和“../demo”两个目录,在表示目录时可以根据makefile所在的当前路径灵活应用绝对路径或者是相对路径的表示方式。目录之间使用“:”进行隔开。

除了使用VPATH变量还可以利用“vpath”关键字实现文件的搜索。其使用方法有三种,如下所示:

vpath <pattern> <dir> :

       在指定目录<dir>中寻找符合<pattern>模式的文件;

vpath <pattern> :

       清除符合<pattern>模式的文件的搜索目录;

vpath :

       清除所有设置的文件搜索目录。

使用实例如下,<pattern>需要包含%字符,%的意思是匹配零或若干字符:

vpath %.c ../demo

       该语句表示在../demo目录中寻找所有.c结尾的文件,如果某.c文件在当前目录没有找到的话。此外可以连续的使用该关键字以定义不同的搜索策略,make会按照定义vpath 的先后顺序进行搜索。如以下实例所示:

vpath %.c ../demo

vpath %  ../common

vpath %.c ../usr

       以上实例表示.c结尾的文件先在“../demo”目录,然后是“../common”,最后是“../usr”进行寻找。

vpath %.c ../demo: ../usr

vpath %  ../common

以上实例表示.c结尾的文件先在“../demo”目录,然后是“../usr”,最后是“../common”进行寻找。

 

5.8、伪目标

       在5.4小节中所使用的清除目标文件中所使用的“clean”目标,其是一个伪目标,因为其并不需要生成“clean”这个目标文件,make也无法生成有关它的依赖关系,实质上是一个标签,定义这个标签所包含的操作,并通过指明这个标签使其生效。注意:“伪目标”的取名不能与文件同名,不然就失去了“伪目标”意义。为了避免与文件重名的情况,可以通过使用特殊的标记“.PHONY”来表明一个目标是“伪目标”。实例如下:

.PHONY : clean

clean:

       rm test *.o

       利用“伪目标”只是标签的这一特性,我们可以需要同时生成多个可执行的目标文件的时候使用它,实例如下:

all : demo1 demo2 demo3

.PHONY : all

demo1 : demo1.o common.o

       cc –o demo1 demo1.o common.o
demo2 : demo2.o common.o

       cc –o demo1 demo1.o common.o
demo3 : demo3.o

       cc –o demo3 demo3.o

 

5.9、多目标

       Makefile中目标文件可以不止一个,其支持多目标文件的处理。当我们实际遇到多个目标文件同时依赖一个文件,并且生成的目标文件的命令也类似的时候我们就可以对makefile进行相应的简化。(此处引入自动化变量“$@”的使用,该变量所表示的是当前规则中,所有目标文件的集合,再命令中使用该变量,“$@”会依次取出目标文件集中的target,并执行命令。)。实例如下:

source = demo.o common.h

output1tool = gcc

output2tool = arm-linux-gcc

output1 output2 : $(source)

       $(subst ,tool,$@) $(source) –o $@

上述规则等价于:

source = demo.c common.h

output1tool = gcc

output2tool = arm-linux-gcc

output1 : $(source)

       gcc demo.c –o output1

output2 : $(source)

       arm-linux-gcc demo.c –o output2

 

5.10、命令的编写

5.10.1、显示命令

       make在执行编译过程中会将执行的命令在终端打印出来。在命令前加上“@”,那么在执行命令时该命令就不会在终端进行打印。

       在执行make的时候,加上参数“-n”或者是“—just-print”,那么在makefile中所编写的命令就只会打印出来而不会被执行,该功能可以很好地用来进行makefile的调试,查看makefile的命令的执行流程。

此外,参数“-s”或“–silent”、“–quiet”则是全局禁止命令的显示。

5.10.2、命令执行

       当某个目标需要进行更新时,make会按编写顺序执行其后的命令。如果你要让上一条命令的结果应用在下一条命令时,你应该使用分号分隔这两条命令。实例如下:

①command:

       cd /home/lins

       pwd

②command:

       cd /home/lins; pwd

       在上述实例中,当我们执行make command时,①打印的结果是当前的makefile的路径;②打印结果时“/home/lins”。

5.10.3、忽略出错

       有时候命令的出错并不意味着就是错误的。例如mkdir命令,我们一定需要建立一个目录,如果目录不存在,那么mkdir就成功执行。如果目录存在,那么就出错了。我们之所以使用mkdir的意思就是 一定要有这样的一个目录,于是我们就不希望mkdir出错而终止规则的运行。

       为了在必要的时候忽略命令的出错,我们可以在命令行前加一个“-”,忽略该命令的报错。

       除此之外还有几个有关忽略出错的参数需要提及一下:

1)给make加上“-i”或是“–ignore-errors”参数,那么,Makefile中所有命令都会忽略错误。而如果一个规则是以 .IGNORE 作为目标的,那么这个规则中的所有命令将会忽略错误。这些是不同级别的防止命令出错的方法,你可以根据你的不同喜欢设置。

2)还有一个要提一下的make的参数的是“-k”或是“—keep-going”,这个参数的意思是,如果某规则中的命令出错了,那么就终止该规则的执行,但继续执行其它规则。

5.10.4、定义命令包

       在makefile中如果出现一系列相同的命令,可以为这些相同的命令序列定义一个变量。定义这种命令 序列的语法defin开始,以endef结束。实例如下:

define run_demo

run_demo $(firstword $^)

rm ./*.o

mv

假设run_demo运行时会生成相关的.o文件,生成目标文件后删除这些.o文件,使用的方式如下:

demo : part1.c

       $(run_demo)

如上,我们使用命令包,就和使用变量一样,其中命令包“run_demo”中的$^表示的是依赖文件part1.c。make在执行命令包时,会将命令包中的每个命令依次独立执行。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/117013.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!