2014-08-29 48 views
1

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

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} 

¹其实很多!

+0

你能更具体吗?你想避免哪些重复的声明? – 2014-08-29 17:54:36

+0

即使你可以定义一个子程序,更大的问题是你仍然会调用3次make。你可以将'-V'的多个用途分组到一个,但是你需要一些额外的shell来将它解析成'm4'的3个单独的'-D'选项。关于将两个调用与'openssl'结合起来,你可以做的不多。 – chepner 2014-08-29 17:55:21

+0

@AndrejAdamenko我想减少'cd ... && $ {MAKE} -V'的冗余度,并找到一种“phonier”方式来放置东西。 – 2014-08-29 18:31:32

回答

2

你应该使用外壳的-c选项,这样定义伪指令:

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

注意使用$$$使用bsdmake变量扩展或外壳变量扩展。有了这些定义,您可以像这样重组您的代码:

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来报告错误。你可以在FreeBSD系统上查看/usr/ports/Mk/bsd.port.mk中的COPYTREE_SHARE宏。它很好地说明了这种技术。