[转]make工具

热度 1已有 782 次阅读2012-9-18 09:34 |个人分类:Linux| 工具

        make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。在Linux系统下默认使用 “Makefile”作为makefile文件。如果要使用其他文件作为makefile,则可以在使用make命令时指定-f选项使用不同的 makefile文件。

3.1 makefile的基本语法规则(显式规则)
语法如下:
Targets: Prerequisites
<Tab>Command

说明:
1)Targets:目标,通常为文件名,也可以为自定义名称。可以使用通配符。如果目标是多个文件,则以空格分开。
2)Prerequisites:依赖目标,通常为也文件名。如果其中的某个文件要比目标文件新,那么目标就被认为是“过时的”,是需要重新生成的。
3)Commands:命令行,如果其不与Prerequisites在一行,那么必须以<Tab>键开头,如果和Prerequisites在一行,那么可以用分号作为分隔。
4)如果Prerequisites或Commands太长,可以使用反斜杠“\”作为换行符。

3.2 隐式规则
参考:http://hi.baidu.com/h2hk2k/blog/item/0e2bd21024e0b6cfa6ef3f75.html

3.3 makefile变量
        在makefile中定义的变量,就像C语言中的宏一样,它代表了一个文本字串,在makefile中执行的时候会自动原模原样地展开其在所使用的位置。 与C语言所不同的是,用户可以在makefile中改变其值。在makefile中,变量可以使用在“目标”、“依赖目标”、“命令”或者 makefile的其他部分中。
3.3.1 自定义变量命名规则
        变量的名字可以包括字符(大小写敏感)、数字和下划线,可以是数字开头。
3.3.2 变量的使用
        变量在声明时需要给予初值,而在使用时,需要在变量名前加上“$”,但是如果变量名的长度超过一个字符,在引用时就必须添加圆括号“()”或是大括号“{}”把变量括起来。如果要使用真实的“$”字符,那么需用“$$”来表示。
3.3.3 makefile预定义变量

1)$@:表示规则中的目标文件集。
2)$+:所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
3)$^:所有的依赖文件,以空格分开,不包含重复的依赖文件。
4)$?:所有比目标新的依赖目标的集合。
5)$<:第一个依赖文件的名称。
6)$*:不包含扩展名的目标文件名称。

3.4 环境变量
        make工具支持环境变量,通过设置环境变量的值,可以改变make的默认动作。
3.4.1 VPATH环境变量
        在一些大的工程中,有大量的源文件,我们通常的做法是把许多的源文件分类,并存放在不同的目录中。所以,当make需要去寻找文件的依赖关系时,可以在文 件前加上路径,但最好的方法是把一个路径告诉make,让它去自动查找。环境变量VPATH就是完成这个功能的,如果没有指明这个变量,make只会在当 前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,make就会在当前目录找不到的情况下,到所指定的目录中,按照指定的顺序进行查找。例如:
VPATH=/home/include/headers1:/home/include/headers2
如果存在多个目录,则目录间由冒号分隔。
3.4.2 CFLAGS环境变量
        指定了C语言编译器参数。
3.4.3 LDFLAGS环境变量
        指定了C语言链接器参数。

3.5 通配符
        make支持3个通配符:“*”、“?”、“[...]”。另外,波浪号“~”字符在文件名中也有比较特殊的用途。例如“~/test”表示当前用户的$HOME目录下的test目录。

3.6 使用条件判断
        使用条件判断,可以让make根据运行时的不同情况选择不同的执行分支。条件表达式可以是比较变量的值,或是比较变量和常量的值。语法如下:
<conditional-directive>
<text-if-true>
endif

或者:
<conditional-directive>
<text-if-true>
else
<text-if-false>
endif

其中,<conditional-directive>代表条件关键字,共有4个:ifeq、ifneq、ifdef、ifndef。
3.6.1 ifeq语法
ifeq (<arg1>,<arg2>)
ifeq '<arg1>' '<arg2>'
ifeq "<arg1>" "<arg2>"
ifeq "<arg1>" '<arg2>'
ifeq '<arg1>' "<arg2>"

ifeq用于比较参数arg1和arg2的值是否相同。如果相同则返回真,否则返回假。
3.6.2 ifneq语法
ifneq (<arg1>,<arg2>)
ifneq '<arg1>' '<arg2>'
ifneq "<arg1>" "<arg2>"
ifneq "<arg1>" '<arg2>'
ifneq '<arg1>' "<arg2>"

ifneq用于比较参数arg1和arg2是否不同,如果不同则返回真,否则返回假。
3.6.3 ifdef语法
ifdef <variable-name>
如果变量<variable-name>的值非空,那么表达式为真;否则,表达式为假。
3.6.4 ifndef语法
ifndef <variable-name>
如果变量<variable-name>的值为空,那么表达式为真;否则,表达式为假。

注意:使用条件判断时,不应该加前缀<Tab>键,否则,将被解释为命令。

3.7 在makefile中使用函数
        makefile支持函数调用。通过使用函数,可以使makefile的使用更为灵活。函数调用后的返回值可以在makefile中获取,用户可以根据返回值进行下一步的处理。使用函数的语法为:
$(<函数名> <参数1>,<参数2> <...>)
参数间以逗号“,”分隔,而函数名和参数之间以“空格”分隔。
常用的makefile函数包括以下几个。
3.7.1 字符串替换函数 substr
$(substr <from>,<to>,<text>)
功能:将字符串text中from的内容替换为to。
3.7.2 去空格函数 strip
$(strip <string>)
功能:将字符串string中的前后空格去掉
3.7.3 查找字符串函数 findstring
$(findstring <find>,<in>)
功能:在字符串in中查找与find指定内容匹配的字串。如果查找成功,则返回find指定的串,否则返回空串。
3.7.4 排序函数 sort
$(sort <list>)
其中,list是待排序的字符串集合,返回值是经过排序后的字符串集合。需要注意的是,sort函数将对重复的串进行过滤,只保留一次。
3.7.5 取目录函数 dir
$(dir <path>)
功能:从路径path取出目录部分并返回
3.7.6 取前缀函数 basename
$(basename <filename>)
功能:从文件名filename中取出,去掉后缀(.及后面的部分)后的内容并返回。
3.7.7 变量来源函数 orgin
$(orgin <var>)
功能:返回变量的来源。可能的来源包括以下几点:
1)Undefined:变量未定义过。
2)Defualt:默认的变量定义。
3)File:在makefile中定义的变量
4)Command line:在命令行中定义的变量,如在make的命令行中定义的变量等。

3.8 make命令的工作过程
        make命令的工作是按照一定规则进行的。通常情况下,一个make命令的工作过程如下:
1)读入makefile,make是在当前目录下查找makefile或者Makefile的。如果用户通过-f指定其他makefile名称,则按照用户指定的文件去查找。
2)初始化makefile文件中的变量,如果makefile包含了其他的makefile,则加载之。
3)推导隐含规则,并分析所有规则,检查各种要素间的依赖关系,为所有的目标文件创建依赖关系链。
4)根据依赖关系,检查哪些依赖项发生了变更,分析哪些文件需要重新生成。
5)执行生成命令。

3.9 在makefile中使用伪目标
        根据GNU规范的要求,建议在makefile中使用伪目标,常用的伪目标有:all,clean,install,print等。

3.10 make命令的返回值
        make命令执行完成后,可以依据make的返回值查询make运行的结果。可以通过shell命令“echo $?”查看make的返回值。make返回值有以下3种:
1)0:表示成功执行。
2)1:如果make运行时出现任何错误,返回1。
3)2:如果使用了make的-q选项,并且make使得部分目标不需要更新,则返回2。

3.11 makefile知识参考
Ubuntu Wiki:
http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:MakeFile%E4%BB%8B%E7%BB%8Dv
转自:http://blog.163.com/ljf_gzhu/blog/static/1315534402011822102010929/

路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (2 个评论)

回复 LvL_wxfg 2012-9-18 11:55
  
回复 liuasdj 2012-9-21 09:30
LvL_wxfg:   
    这只是一个小小的开始,,,,

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

返回顶部