2012-11-29 35 views
3

我有一個makefile規則,它根據列表的內容生成一個C文件。make echo在生成的文件中包含引號

LIST = foo \ 
     bar 

generated.c: 
    @echo "Creating [email protected]" 
    (echo "#include <stuff.h>";  \ 
    echo "void init_local() {";  \ 
    for i in $(LIST) ; do   \ 
     echo " init_$$i();";  \ 
    done; 
    echo "}") > [email protected] 

在Linux平臺上,這給了我,我希望得到的結果:

#include <stuff.h> 
void init_local() { 
    init_foo(); 
    init_bar(); 
} 

然而,在我的Windows 7 64位平臺與GNU使3.82(x86_64的-W64-的mingw32),
我得到以下(全部在一行上):

"#include <stuff.h>"; \"void init_local() {" \ 
    for i in foo bar; do echo " init_$i();"; done; echo "}" 

我也試圖擺脫對個別行的規則:

echo "#include <stuff.h>" > %@ 
    echo "void init_local() {" >> [email protected] 
    ... 

有了這個解決方案,我每行有1個字符串,但引號仍然存在!

如何更改規則以在Linux和Windows平臺上生成正確的文件?

回答

1

這是因爲DOS有自己的命令分隔符 - &(類似於;在bash)。不過,我會建議使用使回聲,而不是外殼回聲將在DOS和在bash工作:

但是,這還不是全部,因爲我知道你並不需要引號(「」)的輸出,即爲什麼你不應該通過它們回聲,而是用^轉義特殊符號。

ifeq ($(OS_TYPE),linux) 
    Q=" 
    ESC= 
else 
    Q= 
    ESC=^ 
endif 

generated.c: 
    @echo "Creating [email protected]" 
    echo $(Q)#include $(ESC)<stuff.h$(ESC)>$(Q) > [email protected] 
    echo $(Q)void init_local() {$(Q) >> [email protected] 
    ... 

此外,你的bash for ..; do ..; done;循環應該替換爲make $(foreach,$(LIST),echo ...)對於兩個shell都是正確的。

是的,我知道,這看起來很醜陋,但那是因爲奇怪的DOS規則。如果您需要生成很多,我會建議使用awk,python或perl。

+0

我確實嘗試過,但引號仍然迴應!辣媽! – Benoit

+1

是的,我只是在寫這些,我已經花了很多時間在我以前的工作上生成與不同的瘋狂的DOS轉義作鬥爭的文件,但後來我決定使用Perl。 – pmod

+0

這很好。 – Benoit