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; 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 $?
以上罗列的自动量变量中。其中有四个在规则中代表文件名($@、$<、$%、$*)。而其它三个的在规则中代表一个文件名列表。