Makefile中的常用变量与函数,Makefile所有内嵌函数

作者: 今晚买四不像计算  发布:2019-10-22

Makefile中的预订义变量:

大器晚成、文本管理函数
以下是GNU make内嵌的文书(字符串)管理函数。
1       $(subst FROM,TO,TEXT)

  • CC,C语言编写翻译器的名称,cc
  • CPP, C语言预管理器的称呼,$(CC) -E
  • CXX, C++语言的编写翻译器名称,g++
  • RM,删除文件程序的名目,rm -f
  • CFLAGS, C语言编写翻译器的编写翻译选项,无暗中认可值
  • CPPFLAGS,C语言预管理器的编写翻译选项,无默许值
  • CXXFLAGS,C++语言编译器的编写翻译选项,无默许值

函数名称:字符串替换函数—subst。

 注:在采用RM时,经常接受如下语句: -$(RM) $(TACR-VGET) $(OBJS), 符号“-”表示在操作战败时不报错,而是继续实践。比如在荒诞不经TALANDGET时将继承删除OBJS。

函数效率:把字串“TEXT”中的“FROM”字符替换为“TO”。

Makefile中的自动变量:

再次来到值:替换后的新字符串。

  • $*, 表示指标文件的称号,不含有扩张名
  • $@, 表示指标文件的称号,满含扩充名
  • $+, 表示具有的注重性文件,以空格隔绝,恐怕包涵重复的文本
  • $^, 表示全数的信任文件,以空格隔离,不重复
  • $<, 表示信任性中首先个依赖文件的称呼
  • $?, 正视项中,全体比指标文件新的正视性文件

示例:

招来路线:

$(subst ee,EE,feet on the street)

  • VPATH,路线之间用:隔离

轮换“feet on the street”中的“ee”为“EE”,结果获得字符串“fEEt on the strEEt”。
2       $(patsubst PATTERN,REPLACEMENT,TEXT)

宣称伪指标:

函数名称:形式替换函数—patsubst。

  • .PHONY:clean

函数功效:寻觅“TEXT”中以空格分开的单词,将否切合形式“TATTE812 SuperfastN”替换为“REPLACEMENT”。参数“PATTE中华VN”中能够动用形式通配符“%”来代表一个单词中的若干字符。借使参数“REPLACEMENT”中也蕴藏一个“%”,那么“REPLACEMENT”中的“%”将是“TATTE哈弗N”中的那叁个“%”所表示的字符串。在“TATTE福睿斯N”和“REPLACEMENT”中,独有首先个“%”被视作形式字符来管理,之后出现的不再作格局字符(作为多个字符)。在参数中只要须要将首先个冒出的“%”作为字符本身而不作为方式字符时,可利用反斜杠“”举行转义管理。

Makefile中的函数:

重返值:替换后的新字符串。

  • wildcard, 用法$(wildcard PATTEPRADON), 查找当前目录下具备相符PATTE君越N的文本,再次来到文件名,用空格隔开分离,如$(wildcard *.c)
  • patsubst, 用法$(patsubst PATTETiggoN,REPLACEMENT,SOURCE), 查找SOURCE中切合PATTETiguanN的单词,用REPLACEMENT法则替换,注意,要使用%通配符表示0到n个字符。例:$(patsubst %.c, %.o, $(wildcard *.c))
  • foreach,平时用于多目录下文件的遍历。用法$(foreach VA凯雷德,LIST,TEXT), 将LIST字符串中一个空格分隔的单词,先传给VARubicon,再施行TEXT的表达式,TEXT表达式的重回值作为任何foreach的重回值。

函数表明:参数“TEXT”单词之间的三个空格在拍卖时被合併为一个空格,并忽略前导和最终空格。

图片 1

示例:

$(patsubst %.c,%.o,x.c.c bar.c)

  把字串“x.c.c bar.c”中以.c结尾的单词替换到以.o结尾的字符。函数的归来结果是“x.c.o bar.o”

  变量的更迭引用,它是贰个简化版的“patsubst”函数在变量援引进度的兑现。变量替换援用中:

$(VAR:PATTERN=REPLACEMENT)

  就相当于:

$(patsubst PATTERN,REPLACEMENT,$(VAR))

 

而其他如火如荼种尤其轻松的更迭字符后缀的落到实处:

$(VAR:SUFFIX=REPLACEMENT)

它等于:

$(patsubst %SUFFIX,%REPLACEMENT,$(VAR))

  举个例子大家存在三个意味全数.o文件的变量。定义为“objects = foo.o bar.o baz.o”。为了获得那么些.o文件所对应的.c源文件。大家能够利用以下二种格局的人身自由一个:

$(objects:.o=.c)

$(patsubst %.o,%.c,$(objects))
patsubst多个操作数用逗号隔断
效果与利益:将foo的保有由空格隔离的字符串尾的.c用.o代替
一念之差提醒:Makefile:4: *** insufficient number of arguments (2) to function `patsubst'.  Stop.
格式譬喻:bar := $(patsubst %.c,%.o,$(foo))
3       $(strip STRINT)

函数名称:去空格函数—strip。

函数功用:去掉字串(若干单词,使用几何空字符分割)“STCRUISERINT”初步和终极的空字符,并将内部四个三回九转空字相符併为贰个空字符。

重回值:无前导和结尾空字符、使用单风度翩翩空格分割的多单词字符串。

函数表明:空字符包含空格、[Tab]等不可呈现字符。

示例:

STR =        a    b c    

LOSTR = $(strip $(STR))

结果是“a b c”。

“strip”函数平常用在法规推断语句的表达式中,确定保障表明式相比较的保障和矫健!
4       $(findstring FIND,IN)

函数名称:查找字符串函数—findstring。

函数成效:寻觅字串“IN”,查找“FIND”字串。

再次来到值:要是在“IN”之中存在“FIND”,则赶回“FIND”,不然重临空。

函数表达:字串“IN”之中能够包罗空格、[Tab]。寻觅需若是严俊的文书相配。

示例:

$(findstring a,a b c)

$(findstring a,b c)

先是个函数结果是字“a”;首个值为空字符。
5       $(filter PATTERN…,TEXT)

函数名称:过滤函数—filter。

函数功效:过滤掉字串“TEXT”中持有不切合形式“PATTELacrosseN”的单词,保留全数相符此方式的单词。能够行使八个情势。情势中貌似须求富含格局字符“%”。存在七个格局时,形式表明式之间采纳空格分割。

重返值:空格分割的“TEXT”字串中全体相符格局“PATTE君越N”的字串。

函数表明:“filter”函数能够用来去除四个变量中的某个字符串,大家下边包车型地铁事例中正是用到了此函数。

示例:

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

foo: $(sources)

cc $(filter %.c %.s,$(sources)) -o foo

  使用“$(filter %.c %.s,$(sources))”的重临值给cc来编写翻译生成靶子“foo”,函数再次来到值为“foo.c bar.c baz.s”。
6       $(filter-out PATTERN...,TEXT)

函数名称:反过滤函数—filter-out。

函数功效:和“filter”函数实现的成效相反。过滤掉字串“TEXT”中持有切合情势“PATTE瑞鹰N”的单词,保留全数不切合此形式的单词。能够有四个格局。存在多少个格局时,情势表明式之间利用空格分割。。

再次回到值:空格分割的“TEXT”字串中拥有不符合形式“PATTEEnclaveN”的字串。

函数表达:“filter-out”函数也足以用来去除一个变量中的有个别字符串,(完毕和“filter”函数相反)。

示例:

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

mains=main1.o main2.o

 

$(filter-out $(mains),$(objects))

兑现了剔除变量“objects”中“mains”定义的字串(文件名)成效。它的重临值为“foo.o bar.o”。
7       $(sort LIST)

函数名称:排序函数—sort。

函数作用:给字串“LIST”中的单词以首字母为准实行排序(升序),并去掉重复的单词。

重回值:空格分割的远非重新单词的字串。

函数表达:七个职能,排序和去字串中的重复单词。可以单独行使此中四个功用。

示例:

$(sort foo bar lose foo)

  重回值为:“bar foo lose” 。
8       $(word N,TEXT)

函数名称:取单词函数—word。

函数成效:取字串“TEXT”中第“N”个单词(“N”的值从1开头)。

再次回到值:再次回到字串“TEXT”中第“N”个单词。

函数表达:若是“N”值大于字串“TEXT”中单词的数量,再次来到空字符串。要是“N”为0,出错!

示例:

$(word 2, foo bar baz)

重临值为“bar”。
9       $(wordlist S,E,TEXT)

函数名称:取字串函数—wordlist。

函数功效:从字串“TEXT”中收取从“S”早先到“E”的单词串。“S”和“E”表示单词在字串中地方的数字。

重回值:字串“TEXT”中从第“S”到“E”(包蕴“E”)的单词字串。

函数表明:“S”和“E”都是从1上马的数字。

当“S”比“TEXT”中的字数大时,再次来到空。借使“E”大于“TEXT”字数,重返从“S”伊始,到“TEXT”结束的单词串。如若“S”大于“E”,重返空。

示例:

$(wordlist 2, 3, foo bar baz)

重回值为:“bar baz”。
10  $(words TEXT)

函数名称:总计单词数目函数—words。

函数功能:字算字串“TEXT”中单词的数目。

重回值:“TEXT”字串中的单词数。

示例:

$(words, foo bar)

重返值是“2”。所以字串“TEXT”的结尾八个单词就是:$(word $(words TEXT),TEXT)。
11  $(firstword NAMES…)

函数名称:取首单词函数—firstword。

函数效用:取字串“NAMES…”中的第4个单词。

重临值:字串“NAMES…”的率先个单词。

函数表明:“NAMES”被以为是使用空格分割的多少个单词(名字)的行列。函数忽视“NAMES…”中除第二个单词以外的装有的单词。

示例:

$(firstword foo bar)

再次来到值为“foo”。函数“firstword”完毕的效劳等效于“$(word 1, NAMES…)”。

 

如上12个函数是make内嵌的的文本管理函数。书写Makefile时可选配使用来兑现复杂功效。最后大家应用这一个函数来贯彻贰个实际利用。例子中大家利用函数“subst”和“patsbust”。Makefile中得以选拔变量“VPATH”来钦定寻找路线。对于源代码所包含的头文件的检索路径必要选择gcc的“-I”参数钦赐目录来得以完结,“VPATH”罗列的目录是用冒号“:”分割的。如下正是Makefile的部分:

……

VPATH = src:../includes

override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))

…….

那么第二条语句所完成的意义便是“CFLAGS += -Isrc –I../includes”。

二、文件名处理函数

GNU make除援救文本管理函数之外,还帮衬部分针对于文件名的处理函数。那么些函数首要用来对龙腾虎跃种种空格分割的公文名张开转移,那几个函数的参数被当做若干个文件名来对待。函数对作为参数的黄金年代组文件名依照一定措施张开始拍录卖并回到空格分割的五个文件名类别。
1       $(dir NAMES…)

函数名称:取目录函数—dir。

函数功效:从文件名系列“NAMES…”中抽取各种文件名的目录部分。文件名的目录部分正是带有在文书名中的最终贰个斜线(“/”)(蕴涵斜线)早先的意气风发对。

重临值:空格分割的文本名体系“NAMES…”中各种文书的目录部分。

函数表明:假如文件名中没有斜线,认为此文件为当前目录(“./”)下的文件。

示例:

$(dir src/foo.c hacks)

重回值为“src/ ./”。
2       $(notdir NAMES…)

函数名称:取文件名函数——notdir。

函数功用:从文件名系列“NAMES…”中收取非目录部分。目录部分是指最后五个斜线(“/”)(满含斜线)此前的局地。删除全部文件名中的目录部分,只保留非目录部分。

重返值:文件名体系“NAMES…”中每二个文书的非目录部分。

函数表明:倘若“NAMES…”中留存不含有斜线的公文名,则不改动这几个文件名。以反斜线结尾的文件名,是用空白替代,因而当“NAMES…”中留存多少个这么的文本名时,重返结果中分割种种文件名的空格数目将不明确!那是此函数的叁个毛病。

示例:

$(notdir src/foo.c hacks)

  再次回到值为:“foo.c hacks”。
3       $(suffix NAMES…)

函数名称:取后缀函数—suffix。

函数功用:从文件名体系“NAMES…”中抽取各样文件名的后缀。后缀是文件名中最后三个以点“.”初始的(包蕴点号)部分,假如文件名中不包蕴七个点号,则为空。

再次来到值:以空格分割的文书名连串“NAMES…”中每多少个文件的后缀体系。

函数表达:“NAMES…”是两个公文名时,重临值是三个以空格分割的单词连串。如果文件名未有后缀部分,则赶回空。

示例:

$(suffix src/foo.c src-1.0/bar.c hacks)

重返值为“.c .c”。
4       $(basename NAMES…)

函数名称:取前缀函数—basename。

函数效率:从文件名类别“NAMES…”中抽出各种文件名的前缀部分(点号之后的风流倜傥部分)。前缀部分指的是文件名中最终八个点号早前的一些。

再次来到值:空格分割的公文名类别“NAMES…”中逐个文件的前缀体系。纵然文件未有前缀,则赶回空字串。

函数表达:假若“NAMES…”中带有未有后缀的文书名,此文件名不改动。假使四个文本名中存在多少个点号,则再次来到值为此文件名的最后贰个点号以前的文件名部分。

示例:

$(basename src/foo.c src-1.0/bar.c /home/jack/.font.cache-1 hacks)

  再次来到值为:“src/foo src-1.0/bar /home/jack/.font hacks”。
5       $(addsuffix SUFFIX,NAMES…)

函数名称:加后缀函数—addsuffix。

函数成效:为“NAMES…”中的每三个文本名增加后缀“SUFFIX”。参数“NAMES…”为空格分割的公文名系列,将“SUFFIX”追加到此行列的每一个文本名的末梢。

重回值:以单空格分割的加多了后缀“SUFFIX”的文书名类别。

函数表达:

示例:

$(addsuffix .c,foo bar)

重返值为“foo.c bar.c”。
6       $(addprefix PREFIX,NAMES…)

函数名称:加前缀函数—addprefix。

函数功效:为“NAMES…”中的每贰个文书名加多前缀“PREFIX”。参数“NAMES…”是空格分割的文书名体系,将“SUFFIX”加多到此行列的每八个文书名在此之前。

重回值:以单空格分割的增加了前缀“PREFIX”的文本名类别。

函数表明:

示例: 

$(addprefix src/,foo bar) 

再次回到值为“src/foo src/bar”。
7       $(join LIST1,LIST2)

函数名称:单词连接函数——join。

函数功用:将字串“LIST1”和字串“LIST2”各单词举行相应连接。便是将“LIST2”中的第多个单词追加“LIST1”第二个单词字后联合为三个单词;将“LIST2”中的第二个单词追加到“LIST1”的第一个单词之后并统风姿浪漫为一个单词,……依次列推。

再次来到值:单空格分割的联合后的字(文件名)种类。

函数表达:要是“LIST1”和“LIST2”中的字数目不均等时,两个中剩下部分将被充当重回连串的精神振作某个。

示例1:

$(join a b , .c .o)

重临值为:“a.c b.o”。

示例2:

$(join a b c , .c .o)

重临值为:“a.c b.o c”。
8       $(wildcard PATTERN)

函数名称:获取相称情势文件名函数—wildcard

函数效率:列出当前目录下有所适合形式“PATTE福睿斯N”格式的文件名。

重返值:空格分割的、存在当前目录下的持有相符情势“PATTE福睿斯N”的文件名。

函数表明:“PATTE索罗德N”使用shell可识其他通配符,饱含“?”(单字符)、“*”(多字符)等。

示例:

$(wildcard *.c)

再次来到值为当前目录下全部.c源文件列表。

三、foreach函数

函数“foreach”不一样于别的函数。它是贰个循环函数。类似于Linux的shell中的for语句。

“foreach”函数的语法:

  $(foreach VAR,LIST,TEXT)

  函数功效:这么些函数的干活进度是这么的:假使急需(存在变量只怕函数的引用),首先进行变量“VA安德拉”和“LIST”的援用;而表明式“TEXT”中的变量援用不实行。试行时把“LIST”中应用空格分割的单词依次抽取赋值给变量“VAOdyssey”,然后实施“TEXT”表明式。重复直到“LIST”的尾声一个单词(为空时甘休)。“TEXT”中的变量或然函数引用在进行时才被开展,因而后生可畏旦在“TEXT”中留存对“VAENCORE”的引用,那么“VAPAJERO”的值在每贰回展开式将会到的比不上的值。

再次来到值:空格分割的一再表明式“TEXT”的臆度的结果。

看三个例子,定义变量“files”,它的值为八个目录(变量“dirs”代表的a、b、c、d八个目录)下的文件列表:

  dirs := a b c d

files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))

  例子中,“TEXT”的表明式为“$(wildcard $(dir)/*)”。表达式第二遍实行时将拓宽为“$(wildcard a/*)”;首次进行时将打开为“$(wildcard b/*)”;第叁次开展为“$(wildcard c/*)”;….;由此及彼。所以此函数所实现的效率就和一下讲话等价:

  files := $(wildcard a/* b/* c/* d/*)

  当函数的“TEXT”表达式过于复杂时,大家能够透过定义一当中路变量,此变量代表表明式的风姿洒脱局地。并在函数的“TEXT”中引用这些变量。上面包车型客车例证也足以如此来完毕:

  find_files = $(wildcard $(dir)/*)

dirs := a b c d

files := $(foreach dir,$(dirs),$(find_files))

在那处大家定义了三个变量(也得以叫做表明式),必要专心,在这里边定义的是“递归张开”时的变量“find_files”。保险了概念时变量值中的引用不实行,而是在表明式被函数管理时才开展(若是这里运用直接打开式的定义将是不行的表明式)。

  函数表明:函数中参数“VATiguan”是叁个部分的一时变量,它只在“foreach”函数的上下文中有效,它的定义不会影响别的一些概念的同名“VAHighlander”变量的值。在函数的进行进程中它是二个“间接开展”式变量。

 

在利用函数“foreach”时,需求专一:变量“VAPRADO”的名字。大家提议使用叁个单词、最棒能够发挥其意思的名字,不要选取一个想不到的字符串作为变量名。即使施行是不会时有发生错误,但是会令人很费解。

从不人会喜欢这种形式,纵然可能它能够健康工作:

  files := $(foreach Esta escrito en espanol!,b c ch,$(find_files))
四、if函数

函数“if”提供了三个在函数上下文中完毕规范化推断的效果。就如make所补助的条件语句—ifeq同样。

  函数语法:

$(if CONDITION,THEN-PART[,ELSE-PART])

  函数功用:第三个参数“CONDITION”,在函数履行时大意其指引和终极空字符,若是带有对任何变量恐怕函数的引用则张开荒展。要是“CONDITION”的实行理并了结果非空,则条件为真,就将第叁个参数“THEN_PAT昂Cora”作为函数的计量表达式;“CONDITION”的进展结果为空,将第五个参数“ELSE-PART”作为函数的说明式,函数的回到结果为可行表明式的简政放权结果。

   重返值:依照准绳决定函数的重回值是率先个或然第3个参数表明式的乘除结果。当不设有第五个参数“ELSE-PART”,何况“CONDITION”张开为空,函数重回空。

  函数表明:函数的标准化表明式“CONDITION”决定了函数的重临值只好是“THEN-PART”或然“ELSE-PART”多个之一日千里的精兵简政结果。

   函数示例:

  SUBDIR += $(if $(SRC_DIR) $(SRC_DIR),/home/src)

  函数的结果是:假使“SRC_DIWrangler”变量值不为空,则将变量“SRC_DIENVISION”钦定的目录作为二个子目录;不然将引得“/home/src”作为一个子目录。

五、call函数

“call”函数是无与伦比一个足以创造定制化参数函数的援引函数。使用这些函数能够兑现对客商本身定义函数引用。大家能够将四个变量定义为二个繁琐的表明式,用“call”函数依据不相同的参数对它进行举办来获取不一致的结果。

函数语法:

  $(call VARIABLE,PARAM,PARAM,...)

  函数效率:在实行时,将它的参数“PARAM”依次赋值给有时变量“$(1)”、“$(2)”(这一个临时变量定义在“VACR-VIABLE”的值中,参谋下面的事例)…… call函数对参数的多寡未有限定,也得以未有参数值,未有参数值的“call”未有任何实际存在的含义。试行时变量“VAEnclaveIABLE”被举办为在函数上下文有效的暂且变量,变量定义中的“$(1)”作为第多个参数,并将函数参数值中的第一个参数赋值给它;变量中的“$(2)”一样被赋值为函数的第2个参数值;就那样类推(变量$(0)代表变量“VA君越IABLE”本人)。之后对变量“VAEnclaveIABLE” 表达式的计算值。

重返值:参数值“PARAM”依次替换“$(1)”、“$(2)”…… 之后变量“VA景逸SUVIABLE”定义的表明式的计算值。(使用call函数“VA普拉多IABLE”中必然存在“$(1)”、“$(2)”…… )

函数表达:1. 函数中“VAXC60IBLE”是八个变量名,并不是变量引用。因而,日常“call”函数中的“VAKoleosIABLE”中不分包“$”(当然,除非此变量名是三个乘除的变量名)。2. 当变量“VA途胜IBLE”是四个make内嵌的函数名时(如“if”、“foreach”、“strip”等),对“PARAM”参数的行使必要静心,因为不对劲或然不科学的参数将会导致函数的重临值难以逆料。3. 函数中两个“PARAM”之间选拔逗号分割。4. 变量“VA奥迪Q5IABLE”在概念时无法定义为直接展开式!只可以定义为递归张开式。

函数示例:

第黄金年代,来看叁个简短的事例。

示例1:

  reverse =  $(2) $(1)

foo = $(call reverse,a,b)

  变量“foo”的值为“ba”。这里变量“reverse”中的参数定义顺序能够依照供给来调动,并不是内需根据“$(1)”、“$(2)”、“$(3)”…… 那样的相继来定义。

看二个略带复杂一些的例子。大家定义了四个宏“pathsearch”来在“PATH”路线中追寻第多个内定的程序。

示例2:

  pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))

LS := $(call pathsearch,ls)

  变量“LS”的结果为“/bin/sh”。实行进程:函数“subst”将情形变量“PATH”调换为空格分割的寻找路线列表;“addsuffix”构造出可能的可实施程序“$(1)”(这里是“ls”)带路线的欧洲经济共同体文件名(如:“/bin/$(1)”),之后选拔函数“wildcard”相配,最终“firstword”函数取第一个文件名。

 

函数“call”以能够套嵌使用。每大器晚成层“call”函数的调用都为它自身的片段变量“$(1)”等赋值,覆盖上如日中天层函数为它所赋的值。

示例3:

map = $(foreach a,$(2),$(call $(1),$(a)))

o = $(call map,origin,o map MAKE)

 

那么变量“o”的值就为“file file default”。咱们那边运用了“origin”函数。大家深入分析函数的实践进程:首先,“o=$(call map,origin, o map MAKE)”那一个函数调用使用了变量“map”所定义的表明式;使用内嵌函数名“origin”作为它的第二个参数值,使用Makefile中的变量“o map MAKE”作为他的第1个参数值。当使用“call”函数展开后等价于“$(foreach a,o map MAKE,$(origin $(a)))”。

小心:和任何函数一样,“call”函数会保留现身在其参数值列表中的空字符。因而在行使参数值时对空格管理要那几个小心。固然参数中存在多余的空格,函数大概会回到二个莫名神奇的值。为了安全,在变量作为“call”函数参数值早先,应去掉其值中的多余空格。

六、value函数

函数“value”提供了风流洒脱种在不对变量举办扩充的动静下取得变量值的章程。注意:并非说函数会撤除在此以前曾经实行过的更迭扩充。举个例子:定义了二个直接张开式的变量,此变量在概念进程中对别的变量的援引举行替换而获得本身的值。在动用“value”函数取那么些变量举办取值时,得到的是不富含别的引用值。并非将定义进程中的替换张开动作撤除后含有征引的定义值。就是说此进程不可能撤销此变量在概念时早就发生了的更迭打开动作。

函数语法:

$(value VARIABLE)

 

函数成效:不对变量“VASportageIBLE”实行别的进展操作,直接再次来到变量“VACRUISERIBALE”的值。这里“VA纳瓦拉IABLE”是二个变量名,平时不含有“$”(除非总计的变量名),

重回值:变量“VA牧马人IBALE”所定义文本值(假诺变量定义为递归张开式,个中包罗对其余变量只怕函数的援用,那么函数不对那个援用举行进行。函数的再次回到值是含有有援引值)。

函数表达:

示例:

# sample Makefile

FOO = $PATH

 

all:

@echo $(FOO)

@echo $(value FOO)

执行make,能够看见的结果是:第意气风发行事:“ATH”。那是因为变量“FOO”定义为“$PATH”,所以实行为“ATH”(“$P”为空)。

其次行才是我们需求展示的系统景况变量“PATH”的值(value函数获得变量“FOO”的值为“$PATH”)。

七、eval函数

函数功用:函数“eval”是二个相比较奇特的函数。使用它能够在Makefile中组织三个可变的平整组织涉及(正视关系链),在那之中能够接纳任何变量和函数。函数“eval”对它的参数举行实行,打开的结果作为Makefile的一片段,make能够对进行内容打开语法分析。张开的结果能够富含二个新变量、目的、隐含准则也许是总之法则等。也正是说此函数的意义首借使:依据其参数的关系、结构,对它们实行轮换张开。

再次来到值:函数“eval”的重回值时空,也能够说未有重回值。

函数表达:“eval”函数实践时会对它的参数进行三遍开展。第贰次开展进程是由函数本身完成的,第4回是函数张开后的结果被视作Makefile内容时由make分析时展开的。鲜明那豆蔻梢头进度对于使用“eval”函数特别主要。驾驭了函数“eval”三次实行的长河后。实际利用时,要是在函数的进行结果中存在引用(格式为:$(x)),那么在函数的参数中应当使用“$$”来替代“$”。因为那或多或少,所以普通它的参数中会使用函数“value”来取叁个变量的文本值。

作者们看贰个事例。例子看起来就好像特别复杂,因为它回顾了另外的部分定义和函数。然则大家得以思量两点:其如火如荼,平时实际三个模板的定义恐怕比例子中的更为复杂;其二,大家得以兑现贰个繁琐通用的模版,在具备Makefile中包含它,亦可作到一劳永逸。相信那或多或少也许是超越50%工程师所钟情的。

示例:

# sample Makefile 

PROGRAMS    = server client

    

server_OBJS = server.o server_priv.o server_access.o

server_LIBS = priv protocol

    

client_OBJS = client.o client_api.o client_mem.o

client_LIBS = protocol

    

# Everything after this is generic

.PHONY: all

all: $(PROGRAMS)

    

define PROGRAM_template

$(1): $$($(1)_OBJ) $$($(1)_LIBS:%=-l%)

ALL_OBJS   += $$($(1)_OBJS)

endef

    

$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))

    

$(PROGRAMS):

$(LINK.o) $^ $(LDLIBS) -o $@

    

clean:

rm -f $(ALL_OBJS) $(PROGRAMS)

 

来看一下那些事例:它达成的意义是水到渠成“PROGRAMS”的编写翻译链接。例子中“$(LINK.o)”为“$(CC) $(LDFLAGS)”,意思是对具有的.o文件和点名的库文件举行链接。

“$(foreach prog,$(PROGRAM),$(eval $(call PROGRAM_template,$(prog))))”展开为:

server : $(server_OBJS) –l$(server_LIBS)

client : $(client_OBJS) –l$(client_LIBS)

八、origin函数

函数“origin”和任何函数分裂,函数“origin”的动作不是操作变量(它的参数)。它只是赢得此变量(参数)相关的新闻,告诉大家这些变量的出处(定义形式)。

函数语法:

$(origin VARIABLE)

 

函数成效:函数“origin”查询参数“VALANDIABLE”(一个变量名)的出处。

函数表明:“VAHighlanderIABLE”是二个变量名并不是多少个变量的援引。因而普通它不分包“$”(当然,总括的变量名例外)。

重回值:再次回到“VALX570IABLE”的概念形式。用字符串表示。

函数的回来意况有以下二种:

1.        undefined

变量“VAEvoqueIABLE”未有被定义。

2.        default

变量“VAQX56IABLE”是一个默料定义(内嵌变量)。如“CC”、“MAKE”、“RM”等变量。假如在Makefile中重复定义那几个变量,函数重返值将相应发生变化。

3.        environment

变量“VA库罗德IABLE”是贰个系统遭逢变量,何况make未有应用命令行选项“-e”(Makefile中荒诞不经同名的变量定义,此变量未有被代替他)。

4.        environment override

变量“VAEnclaveIABLE”是叁个种类情形变量,况且make使用了命令行选项“-e”。Makefile中存在一个同名的变量定义,使用“make -e”时景况变量值代替了文件中的变量定义。

5.        file

变量“VA昂科威IABLE”在某三个makefile文件中定义。

6.        command line

变量“VA瑞鹰IABLE”在命令行中定义。

7.        override

变量“VA奥迪Q5IABLE”在makefile文件中定义并运用“override”提醒符证明。

8.        automatic

变量“VAHavalIABLE”是自动化变量。

 

函数“origin”再次回到的变量音信对大家书写Makefile是意气风发对如日方升有效的,能够使我们在应用一个变量以前对它值的合法性举行判定。假若在Makefile其包了别的贰个名叫bar.mk的makefile文件。我们必要在bar.mk中定义变量“bletch”(无论它是不是是二个蒙受变量),保障“make –f bar.mk”能够科学实践。别的生龙活虎种处境,当Makefile包蕴bar.mk,在Makefile满含bar.mk以前有平等的变量定义,不过我们不愿意覆盖bar.mk中的“bletch”的定义。后生可畏种办法是:大家在bar.mk中使用提示符“override”注解那个变量。可是它所存在的标题时,此变量无法被别的措施定义的同名变量覆盖,包蕴命令行定义。别的黄金时代种比较灵敏的兑现便是在bar.mk中使用“origin”函数,如下:

ifdef bletch

ifeq "$(origin bletch)" "environment"

bletch = barf, gag, etc.

endif

endif

此地,如若存在景况变量“bletch”,则对它进行重定义。

ifneq "$(findstring environment,$(origin bletch))" ""

bletch = barf, gag, etc.

endif

以那件事例完结了:即便意况变量中早已存在变量“bletch”,无论是还是不是使用“make -e”来实践Makefile,变量“bletch”的值都以“barf,gag,etc”(在Makefile中所定义的)。意况变量不能替代文件中的定义。

假诺“$(origin bletch)”再次来到“environment”或“environment override”,都将对变量“bletch”重新定义。

九、shell函数

shell函数差异于除“wildcard”函数之外的别的函数。make能够使用它来和外界通讯。

函数功效:函数“shell”所达成的职能和shell中的援用(``)一样。达成对命令的扩大。那就象征须求叁个shell 命令作为此函数的参数,函数的回到结果是此命令在shell中的试行结果。make仅仅对它的来回结果举行拍卖;make将函数重返结果中的全部换行符(“n”)只怕有个别“nr”替换为单空格;并去掉末尾的回车符号(“n”)或者“nr”。实行函数张开式时,它所调用的授命(它的参数)得到实行。除对它的援用出现在准则的命令行和递归变量的定义中以外,另外决大非常多状态下,make是在读取分析Makefile时变成对函数shell的扩充。

再次来到值:函数“shell”的参数(二个shell命令)在shell境况中的执行结果。

函数表达:函数本人的重回值是其参数的推行结果,未有实行其余管理。对结果的管理是由make进行的。当对函数的援引出现在准绳的指令行中,命令行在实施时函数才被开展。张开时函数参数(shell命令)的试行是在别的四个shell进程中成就的,因而须求对出现在法则命令行的千家万户“shell”函数引用要求战战栗栗管理,不然会耳熏目染效能(每一流的“shell”函数的参数都会有分别的shell进度)。

示例1:

contents := $(shell cat foo)

将变量“contents”赋值为文件“foo”的内容,文件中的换行符在变量中动用空格代替。

示例2:

files := $(shell echo *.c)

将变量“files”赋值为当前目录下全部.c文件的列表(文件名以内选取空格分割)。在shell中之行的吩咐是“echo *.c”,此命令归来当前目录下的全数.c文件列表。上例的执行结果和函数“$(wildcard *.c)”的结果意气风发致,除非你接受的是叁个出人意料的shell。
留意:通过上边的多少个例证大家得以见见,当援用“shell”函数的变量定义使用直接展开式定义时方可确定保障函数的张开是在make读入Makefile时成功。后续对此变量的援用就不会有进展进程。那样就足避防止法则命令行中的变量援引在命令行试行时张开的事态发生(因为张开“shell”函数须求别的的shell进程完毕,影响命令的推行功用)。那也是我们建议的点子。

十、make的调节函数

make提供了多少个调整make运营情势的函数。平常它们用在Makefile中,当make实践进度中质量评定到一点错误是为客户提供新闻,並且能够操纵make进程是或不是持续。
1  $(error TEXT…)

函数功用:发生致命错误,并提示“TEXT…”音信给客户,并退出make的举行。需求表明的是:“error”函数是在函数张开式(函数被调用时)才提醒消息并结束make进度。由此龙腾虎跃旦函数出现在指令中要么三个递归的变量定义中时,在读取Makefile时不会产出错误。而只有包罗“error”函数援引的吩咐被施行,也许定义中援用此函数的递归变量被开展时,才会提醒致命新闻“TEXT…”同偶然候退出make。

返回值:空

  函数表明:“error”函数平日不出现在直接张开式的变量定义中,不然在make读取Makefile时将会提醒致命错误。

只要大家的Makefile中蕴藏以下多个片断;

示例1:

ifdef ERROR1

$(error error is $(ERROR1))

endif 

make读取剖判Makefile时,固然只起那曾经定义变量“EROOHighlander1”,make将会唤醒致命错误新闻“$(EENCORERO福特Explorer1)”并脱离。

示例2:

ERR = $(error found an error!)

 

.PHONY: err

err: ; $(ERR) 

那个事例,在make读取Makefile时不会现出致命错误。独有指标“err”被看做三个对象被实行时才会冒出。
2  $(warning TEXT…) 

函数功效:函数“warning”类似于函数“error”,不相同在于它不会导致致命错误(make不脱离),而只是提示“TEXT…”,make的施行进度持续。

返回值:空

函数表明:用法和“error”类似,展开进度同样。

本文由今晚买四不像发布于今晚买四不像计算,转载请注明出处:Makefile中的常用变量与函数,Makefile所有内嵌函数

关键词:

上一篇:Linux下的实时代风尚媒体编制程序
下一篇:没有了