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

3

我有一个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个回答

1
这是因为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) >> $@
    ...

此外,您的bash for..;do..;done;循环应该被替换为make $(foreach, $(LIST), echo ...)以便在两个shell中都正确。
是的,我知道,这看起来有点丑,但那是因为奇怪的DOS规则。如果您需要生成大量内容,我建议使用awk、python或perl。

我尝试过,但引号仍然被回显出来了!令人毛骨悚然! - Benoit
1
是的,我刚刚在写关于这个的内容,我在之前的工作中花了很多时间来生成make文件——与不同的疯狂DOS转义斗争,但后来我决定使用perl。 - pmod
好的,很棒,我很高兴这有所帮助。 - pmod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接