如何在Makefile中定义子例程 [英] How to define subroutines in a Makefile
问题描述
我正在处理一个Makefile
,它有一个收据,使用M4生成了一些文件.它使用一些复杂的外壳结构来计算必须传递给M4的宏值.如何组织代码,以避免在下面的示例中显示多余的声明?
I am working on a Makefile
which has a¹ receipt producing some file using M4. It uses some complex shell constructions to compute macro values which have to be passed to M4. How can I organize code to avoid redundant declarations displayed in the following example?
M4TOOL= m4
M4TOOL+= -D PACKAGE=$$(cd ${PROJECTBASEDIR} && ${MAKE} -V PACKAGE)
M4TOOL+= -D VERSION=$$(cd ${PROJECTBASEDIR} && ${MAKE} -V VERSION)
M4TOOL+= -D AUTHOR=$$(cd ${PROJECTBASEDIR} && ${MAKE} -V AUTHOR)
M4TOOL+= -D RDC960=$$(openssl rdc960 ${DISTFILE} | cut -d ' ' -f 2)
M4TOOL+= -D SHA256=$$(openssl sha256 ${DISTFILE} | cut -d ' ' -f 2)
Portfile: Portfile.m4
${M4TOOL} ${.ALLSRC} > ${.TARGET}
¹其实很多!
推荐答案
您应该使用shell的-c
选项定义伪命令,如下所示:
You should define pseudo-commands using the -c
option of the shell, like this:
PROJECTVARIABLE=sh -c 'cd ${PROJECTBASEDIR} && ${MAKE} -V $$1' PROJECTVARIABLE
OPENSSLHASH=sh -c 'openssl $$1 $$2 | cut -d " " -f 2' OPENSSLHASH
请注意使用$
或$$
来使用bsdmake
变量扩展或shell变量扩展.通过这些定义,您可以像下面这样重新组织代码:
Note the use of $
or $$
to use bsdmake
variable expansion or shell variable expansion. With these defintions you can reorganise your code like this:
M4TOOLS+= -D PACKAGE=$$(${PROJECTVARIABLE} PACKAGE)
M4TOOLS+= -D VERSION=$$(${PROJECTVARIABLE} VERSION)
M4TOOLS+= -D AUTHOR=$$(${PROJECTVARIABLE} AUTHOR)
M4TOOLS+= -D RMD160=$$(${OPENSSLHASH} rmd160 ${DISTFILE})
M4TOOLS+= -D SHA256=$$(${OPENSSLHASH} sha256 ${DISTFILE})
可以说,结果更易于阅读和维护.编写此类脚本时,请记住使用错误代码和stderr报告错误.
The result is arguably easier to read and maintain. When you write such scripts, remember to use error codes and stderr to report errors.
PS:您可以在FreeBSD系统上的/usr/ports/Mk/bsd.port.mk
中查看COPYTREE_SHARE
宏.很好地说明了该技术.
PS: You can take a look at the COPYTREE_SHARE
macro in /usr/ports/Mk/bsd.port.mk
on a FreeBSD system. It illustrates well the technique.
这篇关于如何在Makefile中定义子例程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!