【发布时间】:2015-03-02 16:44:52
【问题描述】:
我不知道在 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} 的定义。
那个 sn-p 对 GNU Make 的翻译是什么?
【问题讨论】:
-
应该注意的是,在 GNU 中,您不会在目标先决条件之间获得有序保证(尽管没有
-j,我相信假设您通常是安全的做)所以你的“钩子”不一定做你想做的事。 -
@EtanReisner 当然,但这与问题没有直接关系,为了简单起见,我省略了这一点。例如,在 BSD Make 中,有人说
.ORDER: pre-build do-build post-build强制对上述目标进行串行处理。 -
无论有没有
-j,make 都会以相同的顺序遍历先决条件列表。只是使用-j,在开始新的先决条件之前,make 不会等待以前的(非依赖的)先决条件完成(当然,由于先决条件未完成,这可能会导致某些作业以不同的顺序运行)。如果没有-j,则 确实 保证按顺序构建。