MAKEFILE_LIST/CURDIR/MAKECMDGOALS/MAKEOVERRIDES/MAKEFLAGS

http://blog.chinaunix.net/uid-29460203-id-4191975.html

https://www.xuebuyuan.com/1148403.html?mobile=1

https://www.cnblogs.com/gaojian/archive/2012/09/25/2701669.html

1.

字符串替换函数原型:$(subst <from>,<to>,<text>)

例:$(subst , / , , $(APP_PATH) )

2.

.SUFFIXES用于通知make新的扩展名

.SUFFIXES:清空所有的文件拓展名识别

.SUFFIXES:.o .c .s .mix .dep 声明五个文件拓展名

3.

$(filter <pattern>,<text>):从text中过滤出pattern所指的字符串

                        $(filter-out <pattern>,<text>);从text中过滤掉pattern后的字符串

例:$(filter all , $(MAKECMDGOALS) ):从变量MAKECMDGOALS中过滤出all字符串

4.

递归 make 指令应当总是使用变量 MKAE,不是显式命令名称 make ,像如下这样:

subsystem:
cd subdir && $(MAKE)

这个变量的值就是make 被激活所关联的文件名。如果文件名为 /bin/make,那么执行的片段就是 cd subdir && /bin/make。如果你使用一个特殊版本的make 来运行顶层的makefie,那么此版本也会为下层的makefile来递归调用。

作为一个特殊的功能,在一个规则的片段里使用变量 MAKE有 -t(--touch), -n(--just-print), 或者 -q(--question)选项。

使用 MAKE 变量时,在片段行的起始处用 + 符号同样有效。*Note Instead of Executing the Recipes: Instead of Execution

这个特殊的功能只有在 MAKE变量在片段里直接出现的时候才有效。MAKE变量被通过其他变量扩展而来时无效。在之后的场合,你必须使用 + 令牌来获得这些效果。

考虑一下在上述例子中的命令 make -t。(-t 选项标记目的为最新,而没有真正运行任何片段;see *note Instead of Execution::) 

 后面跟着 -t 选项后,此例子中的 make -t 命令会创建一个名字为 subsystem的文件,并且不会做其他的事情。你所真正想要做的是 运行 cd subdir && make -t,但是那样需要执行片段,而 -t 却不需要执行片段。

特殊的功能是的make 作了你想要的。当一个规则的片段行包含了变量 MAKE, 标志 -t -n 和-q 将不会作用到那个行。 包含MAKE的片段行会正常执行而不管标志的存在。通常的 MAKEFLAGS机制传递这些标志到make中(*note Communication Options to a sub-make: Options/Recursion),因此你需要使此文件保持最新,或者打印片段等的要求,会被传播到子系统中。

如果你没有想要向下传递其他的标志,你必须改变MAKEFLAGS标志,像这样:

subsystem:
cd subdir && $(MAKE) MAKEFLAGS=

命令行变量定义确实出现在变量 MAKEOVERRIDES中,并且 MAKEFLAGS 包含一个对此变量的引用。如果你想要正常地向下传递标志,但是不想向下传递命令行变量定义,你可以设置 MAKEOVERRIDES 为空值,像下面这样:

MAKEOVERRIDES =

这么做通常是没有用的。但是有些系统在环境的大小方面有一个小小的限制,把很多的信息放入MAKEFLAGS 可能会超出大小。如果你看到错误信息 '参数列表太长(Arg list too long)',可能就是这个原因造成。(为了严格遵循POSIX.2 的兼容性,如果.POSIX出现在makefile中,那么改变MAKEOVERRIDES 不会影响到 MAKEFLAGS)

有一个类似的变量 MFLAGS,是为了向后兼容性的考虑。它和MAKEFLAGS 一样拥有同样的值,但是它不包含命令行变量定义,并且总是开始于一个连字符除非它是空(MAKEFLAGS 仅当它开始于一个非单字母的时候才开始于一个连字符,例如 --warn-undefined-variables)。MFLAGS在递归make命令中是显式地被传统地使用的,例如像这样:

subsystem:

cd subdir && $(MAKE) $(MFLAGS)

但是现在 MAKEFLAGS 使得这种用法冗余了。如果你想要你的makefile和旧的make兼容,可以使用这个技巧;它也可以和很多现代的make版本一起工作。

如果你想每次在你运行make的时候,用特定的选项,比如 -k(*note Summary of Options: Options Summary),MAKEFLAGS 变量也是有用的。你简单地在环境中给 MAKEFLAGS 设置一个值。

你也可以在一个makefile中设置 MAKEFLAGS ,来指定需要在此makefile中生效的附加标志。(注意你不能用这种方式来用 MFLAGS,那个变量只是为了兼容性;make 不会翻译你一个你给MFLAGS设置的值)

当make翻译了MAKEFLAGS的值,如果这个值之前没有连线符,它首先就插入一个连线符。然后它把这个值用空格分成两半。如果这些值在命令行有选项还解析这些词(-C -f -h -o -W除外,它们的长名字版本被忽略;对一个无效的选项不报错)。

如果你在环境中设置了 MAKEFLAGS,你需要确定不要包含任何严重影响到 make 的动作或者削弱了makefile目的的选项。例如,-t -n 和 -q 选项,如果送入了这样的变量,可能会带来灾难性的后果,至少也是令人惊讶或升起的后果。

你可以写一个测试 make 命令标志的条件式,如通过使用findstring函数处理变量 MAKEFLAGS 来测试标志 -t (*note Functions for String Substitution and Analysis: Text Functions.)。

findstring 函数决定是否一个字符串作为子串出现在另一个字符串中。如果你想要测试 -t 标志,使用t 作为findstring的第一个参数,MAKEFLAGS 作为另一个参数。

例如,这里有一个如何使用 ranlib -t 来 完成 标记某个库为最新的例子:

archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif

+前缀标记那些片段行为递归,因此无论是否使用了-t 标记,它们都将会被执行。*Note Recursive Use of make: Recursion.

原文地址:https://www.cnblogs.com/lelin/p/11628949.html