1. foreach 函数

foreach 函数定义如下:

$(foreach <var>,<list>,<text>)

函数的功能是:把参数 <list> 中的单词逐一取出放到参数 <var> 所指定的变量中,然后再执行 <text> 所包含的表达式。

每一次 <text> 会返回一个字符串,循环过程中,<text> 的返所返回的每个字符串会以空格分割,最后当整个循环结束的时候,<text> 所返回的每个字符串所组成的整个字符串(以空格分隔)将会是 foreach 函数的返回值。

所以 <var> 最好是一个变量名,<list> 可以是一个表达式,而 <text> 中一般会只用 <var> 这个参数来一次枚举 <list> 中的单词。

示例:

filename = 11 22 33 44
files = $(foreach n, $(filename), $(n).cpp)
all:echo $(files)

执行 make 结果

wohu@ubuntu:~/cpp/func$ make
echo  11.cpp  22.cpp  33.cpp  44.cpp
11.cpp 22.cpp 33.cpp 44.cpp
wohu@ubuntu:~/cpp/func$

foreach 中的 <var> 参数是一个临时的局部变量,foreach 函数执行完后,参数 <var> 的变量将不再作用,其作用域只在 foreach 函数当中。

2. if 条件选择函数

定义如下:

$(if <condition>,<then-part>)

$(if<condition>,<then-part>,<else-part>)

if 函数可以包含 else 部分,或者是不包含,即 if 函数的参数可以是两个,也可以是三个。
condition 参数是 if 表达式,如果其返回的是非空的字符串,那么这个表达式就相当于返回真,于是,then-part 就会被计算,否则 else-part 会被计算。

if 函数的返回值是:
如果 condition 为真(非空字符串),那么 then-part 会是整个函数的返回值。
如果 condition 为假(空字符串),那么 else-part 将会是这个函数的返回值。此时如果 else-part 没有被定义,那么整个函数返回空字串符。所以,then-partelse-part 只会有一个被计算。

示例 1:

file = aa
OBJ = $(if $(file), $(file), main.c)
all:echo $(OBJ)

执行 make 结果

wohu@ubuntu:~/cpp/func$ make
echo  aa
aa
wohu@ubuntu:~/cpp/func$

示例 2:

OBJ = $(if $(name), $(name), main.c)
other:echo $(OBJ)

执行 make 结果

wohu@ubuntu:~/cpp/func$ make
echo  main.c
main.c
wohu@ubuntu:~/cpp/func$

3. call 函数

函数定义如下:

$(call <expression>,<parm1>,<parm2>,<parm3>,...)

call 函数是唯一一个可以用来创建新的参数化的函数。我们可以用来写一个非常复杂的表达式,这个表达式中,我们可以定义很多的参数,然后你可以用 call 函数来向这个表达式传递参数。

make 执行这个函数的时候,expression 参数中的变量 $(1)$(2)$(3)等,会被参数 parm1parm2parm3 依次取代。而 expression 的返回值就是 call 函数的返回值。

reverse = $(2) $(1)
foo = $(call reverse, aa, bb)
all:echo $(foo)

执行结果:

wohu@ubuntu:~/cpp/func$ make
echo  bb  aa
bb aa
wohu@ubuntu:~/cpp/func$

4. origin 函数

定义如下:

$(origin <variable>)

origin 函数不像其他的函数,它并不操作变量的值,它只是告诉你这个变量是哪里来的。
注意: variable 是变量的名字,不应该是引用,所以最好不要在 variable 中使用 $ 字符。

下面是 origin 函数返回值:

  • undefined:如果 <variable> 从来没有定义过,函数将返回这个值。
  • default:如果 <variable> 是一个默认的定义,比如说CC这个变量。
  • environment:如果 <variable> 是一个环境变量并且当 Makefile 被执行的时候,-e参数没有被打开。
  • file:如果 <variable> 这个变量被定义在 Makefile 中,将会返回这个值。
  • command line:如果 <variable> 这个变量是被命令执行的,将会被返回。
  • override:如果 <variable> 是被 override 指示符重新定义的。
  • automatic:如果 <variable> 是一个命令运行中的自动化变量。

这些信息对于我们编写 Makefile 是非常有用的,例如假设我们有一个 Makefile ,其包含了一个定义文件 Make.def ,在 Make.def 中定义了一个变量 bletch ,而我们的环境变量中也有一个环境变量 bletch,我们想去判断一下这个变量是不是环境变量,如果是我们就把它重定义了。如果是非环境变量,那么我们就不重新定义它。于是,我们在 Makefile 中,可以这样写:

ifdef bletch
ifeq "$(origin bletch)" "environment"
bletch = barf,gag,etc
endif
endif

当然,使用 override 关键字不就可以重新定义环境中的变量了吗,为什么需要使用这样的步骤?
是的,我们用 override 是可以达到这样的效果的,可是 override 会把从命令行定义的变量也覆盖了,而我们只想重新定义环境传来的,而不是重新定义命令行传来的。

浅显易懂 Makefile 入门 (07)— 其它函数(foreach 、if、call、origin )相关推荐

  1. makefile详解 函数 foreach if call origin shell

       makefile详解 函数 foreach if call origin shell 控制make函数 四.foreach 函数 foreach函数和别的函数非常的不一样.因为这个函数是用来做循 ...

  2. 浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin

    1. 变量的定义 Makefile 文件中定义变量的基本语法如下: 变量的名称=值列表 变量的名称可以由大小写字母.阿拉伯数字和下划线构成.等号左右的空白符没有明确的要求,因为在执行 make 的时候 ...

  3. 浅显易懂 Makefile 入门 (06)— 文件名操作函数(dir、notdir、suffix、basename、addsuffix、addperfix、join、wildcard)

    编写 Makefile 的时候,很多情况下需要对文件名进行操作.例如获取文件的路径,去除文件的路径,取出文件前缀或后缀等等. 注意:下面的每个函数的参数字符串都会被当作或是一个系列的文件名来看待. 1 ...

  4. 浅显易懂 Makefile 入门 (05)— 字符串处理函数(patsubst、subst、strip、findstring、filter、filter-out、sort、word)

    1. 字符串函数格式 函数调用的格式如下: $(<function> <arguments>) 或者是 ${<function> <arguments> ...

  5. 浅显易懂 Makefile 入门 (12)— Makefile 常见的错误信息

    1. 常见的错误信息 make 执行过程中所产生错误并不都是致命的,特别是在命令行之前存在 -.或者 make 使用 -k 选项执行时. make 执行过程的致命错误都带有前缀字符串 ***.错误信息 ...

  6. 浅显易懂 Makefile 入门 (09)— include 文件包含、MAKECMDGOALS

    1. include文件包含 当 make 读取到 include 关键字的时候,会暂停读取当前的 Makefile,而是去读 include 包含的文件,读取结束后再继读取当前的 Makefile ...

  7. 浅显易懂 Makefile 入门 (08)— 默认 shell (/bin/sh)、命令回显、make参数(-n 只显示命令但不执行,-s 禁止所有回显)、单行命令、多行命令、并发执行

    1. shell 相关 1.1 默认 shell Makefile 所使用的命令是由 shell 命令行组成,他们是一条一条执行的. 多个命令之间要使用分号隔开,Makefile 中的任何命令都要以 ...

  8. 浅显易懂 Makefile 入门 (01)— 什么是Makefile、为什么要用Makefile、Makefile规则、Makefile流程如何实现增量编译

    1. 什么是 Makefile Makefile 文件描述了 Linux 系统下 C/C++ 工程的编译规则,它用来自动化编译 C/C++ 项目.一旦写编写好 Makefile 文件,只需要一个 ma ...

  9. 浅显易懂 Makefile 入门 (10)— 嵌套执行 make、export 的使用

    1. 嵌套执行 make 在一个大的工程文件中,不同的文件按照功能被划分到不同的模块中,每个模块可能都会有自己的编译顺序和规则,如果在一个 Makefile 文件中描述所有模块的编译规则,就会很乱,执 ...

最新文章

  1. zabbix items 配置
  2. spring aop 如何切面到mvc 的controller--转载
  3. Java Web系列:Spring MVC基础
  4. 微软也走先使用后收费的路子--创业企业扶植计划(Microsoft BizSpark™)
  5. matlab_simulink笔记01——模块属性的设置以及模块参数的设置
  6. 华为机试——字符个数统计
  7. HTML5 —— 本地存储
  8. win7服务器 能否建立多个网站,windows7下weblogic10.3服务器下一个domain建多个server(端口)...
  9. java字符编码详解_Java中字符编码格式详解
  10. memcache php 到期时间,Memcache PHP会话调优:memcache如何过期密钥?
  11. 华硕笔记本linux触摸板驱动,华硕笔记本触摸板驱动安装教程及打开方法
  12. getElementById(‘divid‘).innerHTML赋值【js基础】
  13. oracle sql中( ),Oracle SQL中的函数
  14. linux系统怎么调节分辨率,直观:Linux下的高分辨率屏幕设置
  15. 联想thinkpad E450如何进入bios
  16. GIONEE A1 金立A1 root 刷机包 GIONEE SWW1609_0201 mt6755
  17. 亿级数据服务平台:跟低效率、指标难统一的数仓说再见!
  18. 全文检索服务 ElasticSearch---------IK分词器的使用
  19. SpringBoot 整合WebSocket 简单实战案例
  20. 说说我理解的互联网共享精神

热门文章

  1. vs2012常用快捷键
  2. c语言中struct和c++中class实例对比
  3. 输入输出导入导出问题
  4. pycharm设置编写的脚本页面长行实现自动换行(windows版)
  5. Python错误:AttributeError: 'generator' object has no attribute 'next'解决办法
  6. LeetCode简单题之连续字符
  7. TensorFlow与PyTorch模型部署性能比较
  8. Linux输入输出I/O
  9. camera数字降噪(DNR)
  10. GPU加速库AmgX