我不知道有什么方法可以在 GNU Make 中以编程方式定义目标。这怎么可能?
有时一个人可以走开用替代方法 https://stackoverflow.com/questions/8937500/how-to-generate-list-of-make-targets-automatically-by-globbing-subdirectories。然而,在 Makefile 中以编程方式定义目标的能力对于编写和组织复杂的生产规则非常重要make
。复杂产生式规则的示例可以在 FreeBSD 的构建系统或 Makefile 库中找到,例如BSD Owl https://github.com/michipili/bsdowl
The 主要区别 https://stackoverflow.com/a/27293153/2654678shell 脚本和 Makefile 之间是:
例如,一个非常简单且有用的模式如下:
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 的翻译是什么?
FWIW 这里是 make 的等效语法
.for _target in configure build test install
.if !target(${_target})
${_target}: pre-${_target}
${_target}: do-${_target}
${_target}: post-${_target}
.endif
.endfor
基本上,你想要make看到这样的片段:
build: pre-build
build: do-build
build: post-build
类似地对于configure
, test
and install
。这表明一个循环eval
某处:
define makerule =
$1: pre-$1
$1: do-$1
$1: post-$1
endef
targets := configure build test install
$(foreach _,${targets},$(eval $(call makerule,$_)))
(要玩这个,改变eval
to info
)。小心那些关闭!
FWIW,这是扩展foreach
:
-
make expands the list to be iterated over
-
${targets}
变成configure
, build
, test
and install
- We have
$(foreach _,configure build test install,$(eval $(call makerule,$_)))
-
_
被设置为第一个值,configure
.
-
make扩大
$(eval $(call makerule,configure))
- To evaluate the
eval
, make expands $(call makerule,configure)
- 它通过设置来做到这一点
1
to configure
,并扩大${makerule}
它产生 3 行文本:
configure: pre-configure
configure: do-configure
configure: post-configure
-
$(eval)
去工作,阅读本文make syntax
- 请注意,扩展
$(eval)
是空的!它的所有工作都是作为副作用完成的。
清洗、起泡、冲洗,重复。
请注意:我必须同意所有其他评论者的观点:你的模式是bad制作。如果你的 makefile 不是-j
安全,那么就是broken(缺少依赖项)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)