如何在Makefile中定义子例程

时间:2014-08-29 17:41:18

标签: shell makefile bsdmake

我正在使用Makefile,其中有一张¹收据使用M4生成一些文件。它使用一些复杂的shell结构来计算必须传递给M4的宏值。如何组织代码以避免在以下示例中显示冗余声明?

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}

¹实际上很多!

1 个答案:

答案 0 :(得分:2)

您应该使用shell的-c选项定义伪命令,如下所示:

PROJECTVARIABLE=sh -c 'cd ${PROJECTBASEDIR} && ${MAKE} -V $$1' PROJECTVARIABLE
OPENSSLHASH=sh -c 'openssl $$1 $$2 | cut -d " " -f 2' OPENSSLHASH

请注意使用$$$来使用bsdmake变量扩展或shell变量扩展。有了这些定义,您可以像这样重新组织代码:

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报告错误。

PS:您可以在FreeBSD系统上查看COPYTREE_SHARE中的/usr/ports/Mk/bsd.port.mk宏。它很好地说明了这项技术。