我不知道有任何方法可以在GNU Make中定义编程目标 . 这怎么可能?
有时一个人可以离开with alternate methods . 但是,在Makefile中定义编程目标的能力对于使用 make
编写和组织复杂的 生产环境 规则非常重要 . 复杂 生产环境 规则的示例可在FreeBSD的构建系统或Makefile库中找到,例如BSD Owl
shell脚本和Makefile之间的main differences是:
-
在Makefile中,程序的状态由命令行和文件系统给出,因此可以在作业中断后恢复作业 . 当然,这需要正确编写Makefile,但即使这很难,但要比使用shell脚本实现类似的效果要容易得多 .
-
在Makefile中,使用建议装饰过程或用钩子装饰它是非常容易的,而这在shell脚本中基本上是不可能的 .
例如,一个非常简单和有用的模式如下:
build: pre-build
build: do-build
build: post-build
这将 build
目标显示为三个目标的组合,一个包含实际指令 do-build
,另外两个是挂钩,在 do-build
之前和之后执行 . 这种模式被许多为BSD Make编写的构建系统使用,它偶然允许对目标进行编程定义,以便可以批量编写:
.for _target in configure build test install
.if !target(${_target})
${_target}: pre-${_target}
${_target}: do-${_target}
${_target}: post-${_target}
.endif
.endfor
.if/.endif
块引入的条件使用户能够使用自己的任何 ${_target}
定义 .
GNU Make的片段翻译是什么?
2 回答
这里的FWIW是make等效语法
基本上,你想让make看到这样的代码片段:
和
configure
,test
和install
类似 . 这暗示了一个带有eval
的循环:(要使用此功能,请将
eval
更改为info
) . 小心那些关闭!FWIW,这是
foreach
的扩展:make扩展要迭代的列表
${targets}
变为configure
,_build
,test
和install
我们有
$(foreach _,configure build test install,$(eval $(call makerule,$_)))
_
设置为第一个值configure
.make expands
$(eval $(call makerule,configure))
要评估
eval
,请展开$(call makerule,configure)
它通过将
1
设置为configure
并展开生成3行文本的${makerule}
来实现此目的:configure: pre-configure
configure: do-configure
configure: post-configure
$(eval)
开始工作,将此文本作为make语法阅读注意
$(eval)
的扩展是空的!它的所有工作都是副作用 . 洗净,起泡,冲洗,重复 .Please note: I have to agree with all the other commenters: your pattern is bad make. If your makefile is not -j safe, then it is broken (missing dependencies).
如果您想要支持并行构建,首先此结构无效;如果你使用
-j
选项调用make,它将同时运行所有三个先决条件规则,因为虽然所有这些规则必须在build
之前完成,但它们都没有相互依赖,所以's no ordering defined (that is, you don' t表示pre-build
必须在do-build
之前完成能跑) .其次,GNU make为programmatically defining rules提供了许多功能 . 目前,GNU make还没有能够搜索已定义的目标,因此没有直接类比
.if !target(...)
.但是,您可以使用
.VARIABLES
变量搜索是否已定义变量 . 因此,如果您需要自己的目标,然后让规则生成器检查,那么一种解决方法是定义变量 .