make echo包含生成文件中的引号

时间:2012-11-29 17:41:20

标签: 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();";       \
    done;
    echo "}") > $@

在Linux平台上,这给了我期望的结果:

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

然而,在我的Windows 7 64位平台上使用GNU Make 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() {" >> $@
    ...

使用该解决方案,我每行有1个字符串,但引号仍在那里!

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

1 个答案:

答案 0 :(得分:1)

这是因为DOS有自己的命令分隔符 - &amp; (类似于bash中的; )。但我建议使用make echo而不是shell回声,它将在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) >> $@
    ...

此外,你的bash for ..; do ..; done; 循环应该替换为make $(foreach,$(LIST),echo ...)对两个炮弹都是正确的。

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