Makfile——基础知识
Posted rainingday
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Makfile——基础知识相关的知识,希望对你有一定的参考价值。
学习Makfile需要掌握的基础知识:
一、基础规则:
目标(target)…:依赖(prerequiries)…
<tab>命令(command) #以TAB开头
make命令的使用:
执行 make 命令时,它会去当前目录下查找名为“Makefile”的文件,并根据它的指示去执行操作,生成第一个目标。
我们可以使用“-f”选项指定文件,不再使用名为“Makefile”的文件,比如:make -f Makefile.build。
我们可以使用“-C”选项指定目录,切换到其他目录里去,比如:make -C a/ -f Makefile.build
我们可以指定目标,不再默认生成第一个目标。make -C a/ -f Makefile.build other_target
二、Makefile 变量
1、定义变量
Makfile的定义变量要用到赋值符,“=”、“:=”、“?=”。还有追加“+=”
make 中对变量的赋值有两种方式:延时变量、立即变量。
A = xxx // 延时变量 变量的真实值取决于它所引用的变量的最后一次有效值。
B ?= xxx // 延时变量,如果这是第一次定义,则赋值成功;如果曾定义过,此赋值无效
C := xxx // 立即变量 变量的真实值取决于:=赋予的值。
D += yyy // 如果 D 在前面是延时变量,那么现在它还是延时变量;如果 D 在前面是立即变量,那么现在它还是立即变量
2、变量的导出(export):
在编译程序时,我们会不断地使用“make -C dir”切换到其他目录,执行其他目录里的 Makefile。如果想让某个变量的值在所有目录中都可见,要把它 export 出来。
比如“CC = $(CROSS_COMPILE)gcc”,这个 CC 变量表示编译器,在整个过程中都是一样的。定义它之后,要使用“export CC”把它导出来。
三、Makfile的模式规则
使用模式规则,至少要包含“%”,否则就是一般规则。目标中的“%”表示对文件名的匹配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c 结尾的文件,类似与通配符,a.%.c 就表示以 a.开头,以.c 结束的所有文件。
当“%”出现在目标中的时候,目标中“%”所代表的值决定了依赖中的“%”值,使用方法如下
%.o : %.c
命令
四、Makefile的自动化变量
作用:通过一行命令来从不同的依赖文件中生成对应的目标。
自动化变量会把模式中所定义的一系列的文件自动的挨个取出,直至所有的符合模式的文件都取完。
自动化变量只应该出现在规则的命令中。
自动化变量 | 描述 |
$@ |
规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模 |
$% |
当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件, |
$< |
依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么 |
$? | 所有比目标新的依赖目标集合,以空格分开。 |
$^ |
所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件, |
$+ | 和“$^”类似,但是当依赖文件存在重复的话不会去除重复的依赖文件。 |
$* |
这个变量表示目标模式中"%"及其之前的部分,如果目标是 test/a.test.c,目标模 |
五、Makfile中使用shell命令:
比如:TOPDIR := $(shell pwd)。这是个立即变量,TOPDIR 等于 shell 命令 pwd 的结果。
六、在 Makefile 中怎么放置第 1 个目标
执行 make 命令时如果不指定目标,那么它默认是去生成第 1 个目标。所以“第 1 个目标”,位置很重要。有时候不太方便把第 1 个目标完整地放在文件前面,这时可以在文件的前面直接放置目标,在后面再完善它的依赖与命令。比如:
1 First_target: // 这句话放在前面 2 .... // 其他代码,比如 include 其他文件得到后面的 xxx 变量 3 First_target : $(xxx) $(yyy) // 在文件的后面再来完善 4 command
七、假想目标(伪目标)
一般的目标名都是要生成的文件,而伪目标不代表真正的目标名,在执行 make 命令的时候通过指定这个伪目标来执行其所在规则的定义的命令。
使用伪目标的主要是为了避免 Makefile 中定义的执行命令的目标和工作目录下的实际文件出现名字冲突。
clean: rm -f $(shell find -name "*.o") rm -f $(TARGET)
如果当前目录下恰好有名为“clean”的文件,规则因为没有依赖,所以目标被认为是最新的,那么执行“make clean”时它就不会执行那些删除命令。为了避免这个问题,我们可以将 clean 声明为伪目标,声明方式如下:
.PHONY : clean
八、Makfile的条件判断
两对关键字:ifeq、ifneq、ifdef 和 ifndef
ifeq用法:
ifeq (<参数 1>, <参数 2>) ifeq ‘<参数 1 >’,‘ <参数 2>’ ifeq “<参数 1>”, “<参数 2>” ifeq “<参数 1>”, ‘<参数 2>’ ifeq ‘<参数 1>’, “<参数 2>”
上述用法中都是用来比较“参数 1”和“参数 2”是否相同,相等则为真。ifneq用法类似,不过,不相等为真。
ifdef用法:
ifdef <变量名>
如果“变量名”的值非空,那么表示表达式为真,否则表达式为假。
九、Makefile常用函数
①函数$(foreach var,list,text)——for each var in list, change it to text。对 list 中的每一个元素,取出来赋给 var,然后把 var 改为 text 所描述的形式。
exp:
objs := a.o b.o
dep_files := $(foreach f, $(objs), .$(f).d) // 最终 dep_files := .a.o.d .b.o.d
②$(wildcard pattern)——pattern 所列出的文件是否存在,把存在的文件都列出来。
exp:
src_files := $( wildcard *.c) // 最终 src_files 中列出了当前目录下的所有.c 文件
以上是关于Makfile——基础知识的主要内容,如果未能解决你的问题,请参考以下文章