Makefile 使echo在生成的文件中包含引号

Makefile 使echo在生成的文件中包含引号,makefile,gnu-make,Makefile,Gnu Make,我有一个makefile规则,它根据列表的内容生成一个C文件 LIST = foo \ bar generated.c: @echo "Creating $@" (echo "#include <stuff.h>"; \ echo "void init_local() {"; \ for i in $(LIST) ; do \ echo " init_$$i();";

我有一个makefile规则,它根据列表的内容生成一个C文件

LIST = foo \
       bar

generated.c:
    @echo "Creating $@"
    (echo "#include <stuff.h>";      \
    echo "void init_local() {";      \
    for i in $(LIST) ; do            \
       echo "    init_$$i();";       \
    done;
    echo "}") > $@
LIST=foo\
酒吧
c:
@回显“创建$@”
(回声“#包括”\
回显“void init_local(){”\
对于以美元为单位的i(列表);是否\
回显“init_u$$i();”\
完成;
回声“}”)>$@
在Linux平台上,这给了我预期的结果:

#include <stuff.h>
void init_local() {
    init_foo();
    init_bar();
}
#包括
void init_local(){
init_foo();
init_bar();
}
但是,在使用GNU Make 3.82(x86_64-w64-mingw32)的windows 7 64位平台上,
我得到以下信息(全部在一行中):

“#包括”\“void init_local(){”
对于foo-bar中的i;do echo“init_$i();”done;echo“}”
我还试图打破个别行的规则:

    echo "#include <stuff.h>" > %@
    echo "void init_local() {" >> $@
    ...
echo“#include”>%@
echo“void init_local(){”>>$@
...
使用该解决方案,我每行有1个字符串,但引号仍然存在


如何更改规则以在Linux和Windows平台上正确生成文件?

这是因为DOS有自己的命令分隔符-&(类似于bash中的)。但我建议使用make echo而不是shell echo,这将在DOS和bash中工作:

但这并不是全部,因为我知道输出中不需要引号(),这就是为什么不应该将它们传递给echo,而是使用^转义特殊符号的原因

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

generated.c:
    @echo "Creating $@"
    echo $(Q)#include $(ESC)<stuff.h$(ESC)>$(Q) > $@ 
    echo $(Q)void init_local() {$(Q) >> $@
    ...
ifeq($(操作系统类型),linux)
Q=”
电子稳定控制系统=
其他的
Q=
电子稳定控制系统=^
恩迪夫
c:
@回显“创建$@”
echo$(Q)#包括$(ESC)$(Q)>$@
echo$(Q)void init_local(){$(Q)>>$@
...
此外,您的bashfor..;do..;done;循环应替换为make$(foreach,$(LIST),echo…,以便对两个shell都正确


是的,我知道,这看起来越来越难看,但这是因为奇怪的DOS规则。如果你需要生成很多文件,我建议你使用awk、python或perl。

我尝试过,但引用仍然重复!奇怪!是的,我只是在写这件事,我在以前的工作中花了很多时间来生成不同版本的文件疯狂的DOS转义,但后来我决定使用perl。好的,很好,我很高兴这有帮助
ifeq ($(OS_TYPE),linux)
    Q="
    ESC=
else
    Q=
    ESC=^
endif

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