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

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

函数

GNUmake支持内置函数和用户自定义函数。函数调用看起来像是变量引用,只不过多了用逗号隔开的参数而已。所有的函数都具有相同的形式:$(function-namearg1[, argn])$之后是函数的名称,接着是函数的参数,参数之间以逗号隔开。

内置函数

内置函数是内嵌于make程序内的函数,可以直接使用。

字符串函数

  • $(filterpattern ..., text)

filter函数将text视为一系列以空格隔开的单词,与pattern比较之后,返回符合的单词(模式必须与单词相匹配,而不能只匹配一部分)。模式可以有多个,只要符合其中一个就会被匹配。模式中采用%作为通配符,当有多个%出现在一个模式中,只有第一个作为通配符,其他的作为字面值。

  • $(filter-outpattern ..., text)

filter-out函数刚好与filter相反,用来选出与模式不相符的每个单词

text = apple pear banana watermelon orange pineapplefiltered = $(filter %apple pear %ge,$(text))not_filtered = $(filter-out %apple pear %.ge, $(text))all :    @echo $(filtered)    @echo $(not_filtered)$ makeapple pear orange pineapplebanana watermelon orange
  • $(findstringstring...,text)

此函数将会从text里搜索string。如果找到了就返回该字符串,否则返回空string没有模式匹配功能。

  • $(subst search-string,replace-string,text)

这是一个不具有模式匹配的搜索替换函数search-stringreplace-string不必是整个单词。

  • $(patsubst search-string,replace-string,text)

这个替换函数具有模式匹配功能。同样的,只能用一个%

sources = hello.c lib.c main.c tom_hello.c tom_lib.cobjects = $(subst .c,.o, $(sources))has_main.c = $(findstring main.c, $(sources))has_main = $(findstring main, $(sources))no_domain = $(findstring domain, $(sources))patsubsted = $(patsubst tom%,jerry%, $(sources))all:    @echo $(objects)    @echo $(has_main.c)    @echo $(has_main)    @echo $(no_domain)    @echo $(patsubsted)$ makehello.o lib.o main.o tom_hello.o tom_lib.omain.cmainhello.c lib.c main.c jerry_hello.c jerry_lib.c
  • $(wordstext)

此函数返回text中单词的数量。

  • $(wordn,text)

此函数返回text中的第n个单词。第一个单词编号为1,如果n的值大于单词的总数,返回空值。

  • $(firstwordtext)

返回text中的第一个单词。等效与$(word 1,text)

  • $(wordlist start,end,text)

此函数返回text中范围从start(含)到end(含)的单词。

  • $(sort list)

sort函数会排序它的list参数并且移除重复的单词。此函数会返回按照字典顺序的不重复的单词列表,以空格分隔。而且,sort还会删除前导和结尾的空格。这里的sortmake内部实现的函数,不是shell里的程序。

  • $(shellcommand)

shell的参数会被扩展(就像所有其他参数)并且传递给subshell执行。然后make读取command的标准输出,并将之作为函数的返回值。输出中所出现的一系列换行符会被缩减成单一的空格,任何末尾的换行被删除。标准错误并不会被返回。

  • $(wildcardpattern...)

wildcard的参数是一个模式列表,他会对每个模式进行扩展。如果扩展的模式找不到符合的文件,返回空字符串。该模式为shell的glob匹配

如果想要判断某个文件是否存在,就可以使用wildcard
dot-emacs-exists := $(wildcard ~/.emacs)

  • $(dirlist...)

dir函数返回list中每个单词的目录部分。

  • $(notdirname...)

返回每个单词的文件名部分。

  • $(suffixname...)

返回由每个单词的扩展名构成的单词列表

  • $(basenamename...)

返回由每个单词的非扩展名部分组成的单词列表

  • $(addsuffix, suffix,name...)

返回由name单词列表中的每个单词前加上suffix前缀构成的新的单词表。

  • $(addprefix,prefix,name...)

  • $(joinprefix-list,suffix-list)

join函数把prefix-list的第i个单词与suffix-list的第i个单词连在一起构成新序列的第i个单词。

流程控制函数

  • $(ifcondition,then-part,else-part)

if函数(可不是条件指令ifne,ifeq,ifdef等)会根据条件表达式的求值结果,从两个宏中选择一个进行扩展。

如果condition扩展之后包含任何字符(包括空格),求值结果为真,会对then-part进行扩展;否则,如果condition扩展之后为空,会对else-part进行扩展。
makecondition求值时,首先会移除前导及末尾的空格。

  • $(errortext)

error函数会使make输出text错误信息和当前makefile的名称行号之后以2这个状态结束运行。

  • $(warntext)

    error类似,输出text的内容,但并不退出。扩展结果为空串。

  • $(foreach variable,list,body)

    foreach函数执行的时候,它将list中的每个单词作为body中的variable进行操作,返回操作的结果。

sources = fat32.c format.c alloca.c main.cdirs = src bin incobjects = $(foreach var,$(sources), $(subst .c,.o, $(var)))full_path = $(foreach var, $(sources), $(addprefix src/, $(var)))do_mkdirs = $(foreach var, $(dirs), $(shell mkdir -p $(var)))all:    @echo $(objects)    @echo $(full_path)    @echo $(do_mkdirs)$ makefat32.o format.o alloca.o main.osrc/fat32.c src/format.c src/alloca.c src/main.c                #产生了三个文件夹

eval函数

  • $(evalcontents)

这个函数很重要。它用来将它后面的文本直接放入make解析器。

首先make会扫描eval的参数并对其中的变量进行扩展,然后make会解析文本进行求值的动作(这里也包含了一次扩展动作,因为普通的在makefile中的文本也会扩展一次),就好像它是输入的文本一样。

eval函数经常用与含有多行文本的宏的展开。一个解析器顶层的宏被扩展成多行文本是不合法的,但是用eval函数可以将展开后的宏直接当做输入的文本,再展开一次之后就放入数据库中了。而eval函数本身的展开结果为空。

注意:定义复杂的宏时要考虑二次展开的问题,然后用eval函数引用这个宏。

用户自定义函数

可以用define定义一个自定义的宏:

define macor-name    contentsendef

用户自定义函数是带有参数的宏,宏定义中的$1$2...是函数的形参,宏的定义就是函数的定义。

调用一个自定义函数的形式是:

  • $(callmacro-name[,param1 ...])

call是一个内置函数,call扩展它的第一个参数并把其他参数依次替换到宏定义中的$1$2...的地方。macro-name之后是宏的参数,以逗号隔开。在函数的内部可以使用$0来访问函数名。

call的参数传递机制很简单。调用时可以为call指定任意个参数。如果宏定义内引用了$n,但是调用时并未指定相应的参数,那么该变量就为空值。如果call的参数比宏的$n引用还多,则被忽略。

注意使用函数是不要随意加前导空格,否则可能回产生难以排查的错误。(但降低了可读性)

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

你可能感兴趣的文章
本地如何连接hbase数据库
查看>>
Maven出错-Missing artifact org.apache.openejb:openejb-core:jar:4.1.0-SNAPSHOT:test
查看>>
dubbo配置文件xml校验报错
查看>>
eclipse生成export生成jar详解
查看>>
oracle 模糊查询忽略大小写
查看>>
Java项目导出可运行的jar文件
查看>>
Java文件夹操作,判断多级路径是否存在,不存在就创建(包括windows和linux下的路径字符分析),兼容Windows和Linux
查看>>
JAVA读取PROPERTIES配置文件
查看>>
Linux中执行shell脚本的4种方法总结
查看>>
BufferedInputStream(缓冲输入流)详解
查看>>
修改linux文件权限命令:chmod
查看>>
Linux vi/vim编辑器常用命令与用法总结
查看>>
如何使用Git Bash Here,将本地项目传到github上
查看>>
eclipse git控件操作 回退到历史提交 重置 删除(撤销)历史的某次提交
查看>>
Oracle | 给表和字段添加注释
查看>>
java比较日期大小及日期与字符串的转换【SimpleDateFormat操作实例】
查看>>
Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence
查看>>
java中System.exit()方法
查看>>
在hbase shell中过滤器的简单使用
查看>>
java静态方法和实例方法
查看>>