博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Makefile函数
阅读量:2241 次
发布时间:2019-05-09

本文共 4782 字,大约阅读时间需要 15 分钟。

Makefile函数


内置函数

所有的函数具有如下的形式:

$(function-name arg1[, argn])

1.call

  • $(call macro-name[, param1 ...])
    call是一个内置于make的函数,call会扩展它的第一个参数并把其余参数依次替换到出现$1 $2 …的地方。macro-name可以是任意的宏或者变量。

2.filter filter-out

  • $(filter pattern ...,text)
  • $(filter-out pattern...,text)
    filter函数会将text视为一系列被空格隔开的单词,与pattern比较之后,接着会返回相符者。filter可以接受多个(被空格隔开的)格式。格式必须是整个单词,才可以将相符的单词放到输出列表中。
    模式中只可以包含一个%字符。如果模式中包含了额外的%字符,那么除了第一个字符都会被视为文字字符(literal character)。
    filter-out函数与filter刚好相反,用来选出与模式不相符的每个单词。

3.findstring

usage:`$(findstring string...,text)`

此函数将会在text里搜索string。如果该字符串被找到了,此函数就会返回string;否则,他会返回空值。

注意:此函数返回的只是“搜索字符串”,而不是它所要找到的包含该字符串的单词。其次,“搜索字符串”无法包含通配符

4.subst patsubst

  • $(subst search-string,replace-string,text)
  • $(patsubst search-pattern,replace-pattern,text)
  • 引用替换:$(variable:serach=replace)
    subst是一个不具有通配符能力的搜索与替换函数。常被用来在文件名列表中将一个扩展名替换成另一个扩展名。
    patsubst具有通配符能力。照例,此处的模式只可以包含一个%字符。切记,search-pattern必须与text整个值进行匹配。
    引用替换可移植。其中search可以是一个简单的字符串,如果是这样的话,只要该字符串出现在一个单词的末尾,就会被替换成replace。此外,search可以包含一个代表统配字符%,如果是这样的话,make会依照patsub的规则进行搜索和替换的操作。

5.words word firstword wordlist

  • $(words text)
  • $(word n,text)
  • $(firstword text)
  • $(wordlist start,end,text)
    说明:words返回text中单词的数量
    word返回text中的地n各单词,第一个单词的编号是1.如果n大于text中单词个数,则返回空。
    firstword返回text中的第一个单词。等效于$(word 1,text)
    wordlist返回text中范围从start(含)到end(含)的单词。编号规则同word

6.sort

  • $(sort list)
    sort函数会排序它的list参数并且移除重复的项目。按照字典顺序排序,以空格分割,删除前导以及结尾的空格。

6.shell

  • $(shell command)
    shell函数的参数会被扩展(就像所有其他的参数)并且传递给subshell来执行。然后make会读取command标准输出,并将之返回成函数的值。输出中所出现的一系列换行符会被缩减成单一空格号,任何接在后面的换行符号都会被删除。标准错误以及任何程序的结束状态都不会被返回

文件名函数

1.wildcard

$(wildcard pattern...)

说明:wildcard函数的参数是一份模式列表,他会对列表中的每个模式进行扩展的动作。如果被扩展的模式找不到相符的文件,则会返回空字符串。

2.dir nodir

  • $(dir list...)
  • $(notdir name...)
    dir函数会返回list中每个单词的目录部分。下面的用户函数会返回包含C源文件的每个子目录:
    source-dirs:=$(sort $(dir $(shell find . -name '*.c')))
    notdir函数会返回文件路径的文件名部分。下面的用户函数会从一个Java源文件返回Java的类名:
    get-java-class-name=$(notdir $(subst .java,,$1))

3.suffix basename addsuffix addprefix join

  • $(suffix name...)
  • $(basename name...)
  • $(addsuffixsuffix,name...)
  • $(addprefixprefix,name...)
  • $(joinprefix-list,suffix-list)
    joindirnotdir的反函数。它会把两个列表的对应元素连接在一起。可以用来重建被dirnotdir分解的列表。

3.流程控制

1.if

  • $(ifcondition,then-part,else-part)
    if函数会根据条件表达式的求值结果,从两个宏中选择一个进行扩展。如果condition扩展之后包含任何字符(即使是空格),那么它的求值结果为真,于是会对then-part惊醒扩展的动作;否则,如果condition扩展之后空无一物,那么它的求值结果为假,于是会对else-part进行扩展的动作。

2.error

  • $(errortext)
    error函数用来输出错误信息。在此函数输出信息之后make会以2这个结束状态终止运行。输出中包含当前makefile的名称、当前的行号以及消息正文。下面实现assert编程结构:
# $(call assert,condition,message)define assert    $(if $1,,$(error Assertion failed: $2))endef# $(call assert-file-exists,wildcard-pattern)define assert-file-exists    $(call assert,$(wildcard $1),$1 dose not exist)endef# $(call assert-not-null,make-variable)define assert-not-null    $(call assert,$($1),The variable "$1" is null)endeferror-exit:    $(call assert-not-null,NON_EXISTENT)

3.foreach

  • $(foreachvariable,list,body)
    这个函数可以让你在反复扩展文本的时候,将不同的值替换进去。(这和你使用不同的参数反复执行函数的状况是不一样的,尽管结果一样)。例如:
letters:=$(foreach letter,a b c d,$(letter))show-words:        #letters has $(words $(letters)) words: '$letters)'$ make# letters has 4 words: 'a b c d'

较不重要的杂项函数

1.strip

  • $(striptext)
    strip函数将会从text中移除所有的前导和接在后面的空格,并以单一空格来替换内部所有空格。此函数常用来清理条件表达式中所使用的变量。

2.origin

  • $(originvariable)
    origin函数将会返回描述变量来自何处的字符串。这个变量可以协助你决定如何使用一个变量的值。比如,如果一个变量来自环境,或许你想要忽略该变量的值;如果该变量来自命令行,你就不会这么做。
# $(call asert-defined,variable-name)define assert-define    $(call assert, \        $(filter-out undefined,$(origin $1)), \        '$1' is undefined)endef

origin的返回值包括:

undefined: 变量尚未定义

default: 变量的定义来自make的内置数据库。如果你改变了内置变量的值,origin所返回的是最近一次的定义来自何处
environment:变量的定义来自环境(未使用–environment-overrides)
environment override:变量的定义来自环境(使用了–environment-overrides)
file:变量的定义来自makefile
command line:变量的定义来自命令行
override:变量的命令来自override指令
automatic:这个变量是make所定义的自动变量

3.warnig

  • $(warningtext)
    warning函数与error类似,不过warning不会导致make结束运行。其他特点相同。
$(if $(wildcard $(JAVAC)),,\    $(warning The java compiler variable,JAVAC ($(JAVAC)),\        is not properly set.))

高级的用户自定义函数

call函数将会把它的每个参数依次绑定到$1$2等编号变量。你可以为call函数指定任意多个参数,你还可以通过$0来访问当前所执行的函数的名称(即变量名称)。使用这个信息,我们可以编写一对调试函数来追踪宏的扩展过程:

# $(debug-enter)debug-enter = $(if $(debug_trace),\                $(warning Entering $0($(echo-args))))# $(debug-leave)debug-leave = $(if $(debug_trace),$(warning Leaving $0))comma := ,echo-args   = $(subst ' ','$(comma) ',\                $(foreach a,1 2 3 4 5 6 7 8 9,'$($a)'))

如果我们要查看函数ab是如何被调用的,可以:

debug_trace = 1define a    $(debug-enter)    @echo $1 $2 $3    $(debug-leave)endefdefine b    $(debug-enter)    $(call a,$1,$2,hi)    $(debug-leave)endeftrace-macro:        $(call b,5,$(MAKE))

对这个makefile执行make后会有如下输出:

$ make

makefile:14: Entering b( ‘5’, ‘make’, ”, ”, ”, ”, ”, ”, ”)
makefile:14: Entering a( ‘5’, ‘make’, ‘hi’, ”, ”, ”, ”, ”, ”)
makefile:14: Leaving a
makefile:14: Leaving b
5 make hi

1.eval与value函数

TODO

转载地址:http://weqbb.baihongyu.com/

你可能感兴趣的文章