2014-08-29 36 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宏。它很好地說明了這種技術。