make函数

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/carolzhang8406/article/details/7194169

make内嵌函数的调用语法:

以“ ” 开 始 表 示 一 个 引 用 。 语 法 格 式 如 下 : ”开始表示一个引用。语法格式如下: (FUNCTION ARGUMENTS),函数名和参数直接用空格扩这tab隔开,如果存在多个参数时,参数之间使用逗号“,”分开。


文本处理函数:

  $(subst FROM,TO,TEXT):把字串“TEXT”中的“FROM”字符替换为“TO”,返回替换后的字符串

  $(patsubst PATTERN,REPLACEMENT,TEXT):搜索“TEXT”中以空格分开的单词,将否符合模式“TATTERN”替换为“REPLACEMENT”。参数“PATTERN”中可以使用模式通配符“%”来代表一个单词中的若干字符。

   $(strip STRINT):去空格函数—strip。

$(findstring FIND,IN):搜索字串“IN”,查找“FIND”字串。

$(filter PATTERN…,TEXT):过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,保留所有符合此模式的单词。

例子

sources := foo.c bar.c baz.s ugh.h

foo: $(sources)

cc ( f i l t e r (filter %.c %.s, (filter(sources)) -o foo


   $(filter-out PATTERN…,TEXT):和“filter”函数实现的功能相反。过滤掉字串“TEXT”中所有符合模式“PATTERN”的单词,保留所有不符合此模式的单词。

示例:

objects=main1.o foo.o main2.o bar.o

mains=main1.o main2.o

$(filter-out ( m a i n s ) , (mains), (mains),(objects))

实现了去除变量“objects”中“mains”定义的字串(文件名)功能。它的返回值为“foo.o bar.o”。


   $(word N,TEXT):取字串“TEXT”中第“N”个单词(“N”的值从1开始)。

  $(wordlist S,E,TEXT):从字串“TEXT”中取出从“S”开始到“E”的单词串。“S”和“E”表示单词在字串中位置的数字。


文件名处理函数:

   $(dir NAMES…):从文件名序列“NAMES…”中取出各个文件名的目录部分。文件名的目录部分就是包含在文件名中的最后一个斜线(“/”)(包括斜线)之前的部分。

$(notdir NAMES…):从文件名序列“NAMES…”中取出非目录部分。目录部分是指最后一个斜线(“/”)(包括斜线)之前的部分。删除所有文件名中的目录部分,只保留非目录部分。

    $(suffix NAMES…):从文件名序列“NAMES…”中取出各个文件名的后缀。后缀是文件名中最后一个以点“.”开始的(包含点号)部分,如果文件名中不包含一个点号,则为空。

   $(basename NAMES…):从文件名序列“NAMES…”中取出各个文件名的前缀部分(点号之后的部分)。前缀部分指的是文件名中最后一个点号之前的部分。

   KaTeX parse error: Expected 'EOF', got '&' at position 62: …名。<br><br><br> &̲nbsp;&nbsp; for…(foreach VAR,LIST,TEXT)

call函数:“call”函数是唯一一个可以创建定制化参数函数的引用函数。使用这个函数可以实现对用户自己定义函数引用。$(call VARIABLE,PARAM,PARAM,…)


make的隐式规则:

1.        编译C程序

“N.o”自动由“N.c”生成,执行命令为“$(CC) -c $(CPPFLAGS) $(CFLAGS)”。

2.        编译C++程序

“N.o”自动由“N.cc”或者“N.C”生成,执行命令为“$(CXX) -c $(CPPFLAGS) $(CFLAGS)”。建议使用“.cc”作为C++源文件的后缀,而不是“.C”

3.        编译Pascal程序

“N.o”自动由“N.p”创建,执行命令时“$(PC) -c $(PFLAGS)”。

4.        编译Fortran/Ratfor程序

“N.o”自动由“N.r”、“N.F”或者“N.f”生成,根据源文件后缀执行对应的命令:

   .f— “$(FC) –c  $(FFLAGS)”

   .F— “$(FC) –c  $(FFLAGS) $(CPPFLAGS)”

   .r— “$(FC) –c  $(FFLAGS) $(RFLAGS)”

5.        预处理Fortran/Ratfor程序

“N.f”自动由“N.r”或者“N.F”生成。此规则只是转换Ratfor或有预处理的Fortran程序到一个标准的Fortran程序。根据源文件后缀执行对应的命令:

    .F — “$(FC) –F $(CPPFLAGS) $(FFLAGS)”

    .r — “$(FC) –F $(FFLAGS) $(RFLAGS)”

6.        编译Modula-2程序

“N.sym”自动由“N.def”生成,执行的命令是:“$(M2C) $(M2FLAGS) $(DEFFLAGS)”。“N.o”自动由“N.mod”生成,执行的命令是:“$(M2C) $(M2FLAGS) $(MODFLAGS)”。

7.        汇编和需要预处理的汇编程序

“N.s”是不需要预处理的汇编源文件,“N.S”是需要预处理的汇编源文件。汇编器为“as”。

“N.o”可自动由“N.s”生成,执行命令是:“$(AS) $(ASFLAGS)”。

“N.s”可由“N.S”生成,C预编译器“cpp”,执行命令是:“$(CPP) $(CPPFLAGS)”。

8.        链接单一的object文件

“N”自动由“N.o”生成,通过C编译器使用链接器(GUN ld),执行命令是:“$(CC) $(LDFLAGS) N.o $(LOADLIBES) $(LDLIBS)”。

此规则仅适用:由一个源文件直接产生可执行文件的情况。当需要有多个源文件共同来创建一个可执行文件时,需要在Makefile中增加隐含规则的依赖文件。例如:

x : y.o z.o

当“x.c”、“y.c”和“z.c”都存在时,规则执行如下命令:

cc -c x.c -o x.o

cc -c y.c -o y.o

cc -c z.c -o z.o

cc x.o y.o z.o -o x

rm -f x.o

rm -f y.o

rm -f z.o

在复杂的场合,目标文件和源文件之间不存在向上边那样的名字对应关系时(“x”和“x.c”对应,因此隐含规则在进行链接时,自动将“x.c”作为其依赖文件)。这时,需要在Makefile中明确给出描述目标依赖关系的规则。

 

通常,gcc在编译源文件时(根据源文件的后缀名来启动相应的编译器),如果没有指定“-c”选项,gcc会在编译完成之后调用“ld”连接成为可执行文件。

9.        Yacc C程序

“N.c”自动由“N.y”,执行的命令:“$(YACC) $(YFALGS)”。(“Yacc”是一个语法分析工具)

10.   Lex C程序时的隐含规则。

“N.c”自动由“N.l”,执行的命令是:“$(LEX) $(LFALGS)”。(关于“Lex”的细节请查看相关资料)


make的隐含变量:

代表命令的变量
AR:函数库打包程序,可创建静态库.a文档。默认是“ar”。
AS:汇编程序。默认是“as”。
CC:C编译程序。默认是“cc”。
CXX:C++编译程序。默认是“g++”。
CO:从 RCS中提取文件的程序。默认是“co”。
CPP:C程序的预处理器(输出是标准输出设备)。默认是“$(CC) -E”。
FC:编译器和预处理Fortran 和 Ratfor 源文件的编译器。默认是“f77”。
GET:从SCCS中提取文件程序。默认是“get”。
LEX:将 Lex 语言转变为 C 或 Ratfo 的程序。默认是“lex”。
PC:Pascal语言编译器。默认是“pc”。
YACC:Yacc文法分析器(针对于C程序)。默认命令是“yacc”。
YACCR:Yacc文法分析器(针对于Ratfor程序)。默认是“yacc -r”。
MAKEINFO:转换Texinfo源文件(.texi)到Info文件程序。默认是“makeinfo”。
TEX:从TeX源文件创建TeX DVI文件的程序。默认是“tex”。
TEXI2DVI:从Texinfo源文件创建TeX DVI 文件的程序。默认是“texi2dvi”。
WEAVE:转换Web到TeX的程序。默认是“weave”。
CWEAVE:转换C Web 到 TeX的程序。默认是“cweave”。
TANGLE:转换Web到Pascal语言的程序。默认是“tangle”。
CTANGLE:转换C Web 到 C。默认是“ctangle”。
RM:删除命令。默认是“rm -f”。

命令参数的变量:
ARFLAGS:执行“AR”命令的命令行参数。默认值是“rv”。
ASFLAGS:执行汇编语器“AS”的命令行参数(明确指定“.s”或“.S”文件时)。
CFLAGS:执行“CC”编译器的命令行参数(编译.c源文件的选项)。
CXXFLAGS:执行“g++”编译器的命令行参数(编译.cc源文件的选项)。
COFLAGS:执行“co”的命令行参数(在RCS中提取文件的选项)。
CPPFLAGS:执行C预处理器“cc -E”的命令行参数(C 和 Fortran 编译器会用到)。
FFLAGS:Fortran语言编译器“f77”执行的命令行参数(编译Fortran源文件的选项)。
GFLAGS:SCCS “get”程序参数。
LDFLAGS:链接器(如:“ld”)参数。
LFLAGS:Lex文法分析器参数。
PFLAGS:Pascal语言编译器参数。
RFLAGS:Ratfor 程序的Fortran 编译器参数。
YFLAGS:Yacc文法分析器参数。

对于多目标模式规则来说,所有规则的目标共同拥有依赖文件和规则的命令行,当文件符合多个目标模式中的任何一个时,规则定义的命令就有可能将会执行;因为多个目标共同拥有规则的命令行,因此一次命令执行之后,规则不会再去检查是否需要重建符合其它模式的目标

自动化变量:
$@
表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a文件为文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式规则中,它代表的是哪个触发规则被执行的目标文件名。
$%
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则的目标是“foo.a(bar.o)”,那么,“$%”的值就为“bar.o”,“$@”的值为“foo.a”。如果目标不是静态库文件,其值为空。
$<
规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表由隐含规则加入的第一个依赖文件。
$?
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代表的是库成员(.o文件)。
$^
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的只能是所有库成员(.o文件)名。一个文件可重复的出现在目标的依赖中,变量“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。
$+
类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库的交叉引用场合。
$*
在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“%”所代表的部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b”时,“$*”的值为“dir/a.foo”。“茎”对于构造相关文件名非常有用。

自动化变量“$*”需要两点说明:
Ø        对于一个明确指定的规则来说不存在“茎”,这种情况下“$*”的含义发生改变。此时,如果目标文件名带有一个可识别的后缀,那么“$*”表示文件中除后缀以外的部分。例如:“foo.c”则“$*”的值为:“foo”,因为.c是一个可识别的文件后缀名。GUN make对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避免使用这个变量。
Ø        当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量为空。
自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新以后的依赖文件进行操作。例如,静态库文件“libN.a”,它由一些.o文件组成。这个规则实现了只将更新后的.o文件加入到库中:
     lib: foo.o bar.o lose.o win.o

             ar r lib $?

以上罗列的自动量变量中。其中有四个在规则中代表文件名($@、$<、$%、$*)。而其它三个的在规则中代表一个文件名列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值