如何正确转义Makefile的数据?

时间:2011-10-04 21:41:37

标签: bash makefile escaping

我正在使用一个将由Makefile使用的bash脚本动态生成config.mk。该文件由:

构成
cat > config.mk <<CFG
SOMEVAR := $value_from_bash1
ANOTHER := $value_from_bash2
CFG

如何确保生成的文件确实包含$value_from_bash*的内容,而不是扩展/解释的内容?我可能需要将$转移到$$\转移到\\,但还有其他字符需要转义吗?也许有一个我没有听说过的特殊文字作业?

空间似乎也很麻烦:

$ ls -1
a b
a
$ cat Makefile
f := a b
default_target:
    echo "$(firstword $(wildcard ${f}))"
$ make
a

如果我使用f := a\ b它有效(使用f := 'a b'之类的引号也不起作用,makefile只会将其视为常规字符)

3 个答案:

答案 0 :(得分:52)

好的,事实证明,Makefile几乎不需要自行转义,但shell解释器执行的命令需要进行转义。

在Makefile中具有特殊含义且需要转义的字符是:

  • sharp(#,comment)变为\#
  • 美元($,变量开头)变为$$

新行不能插入变量中,但为了避免破坏Makefile的其余部分,请在前面加上反斜杠,以便忽略换行符。

太糟糕了,反斜杠本身无法转义(\\仍然是\\而不是\,如您所料。这使得无法在字符串的末尾放置文字斜杠,因为它将使用换行符或后续注释的散列值。一个空格可以放在行的末尾,但也可以放在变量本身。

配方本身被解释为一个shell命令,没有任何花哨的转义,所以你要自己逃避数据,只要想象你正在编写一个shellcript并从其他文件中插入变量。这里的策略是将变量放在单引号之间,只用'转义'\''(关闭字符串,插入文字'并开始一个新字符串)。示例:mornin' all变为'morning'\'' all',相当于"morning' all"

第一个字+通配符问题是由于firstword将带有空格的文件名视为单独的文件名。此外,wildcard使用\展开转义,因此x\ y匹配为一个单词x y,而不是两个单词。

答案 1 :(得分:5)

似乎完整这个问题的答案是在互联网上无处,所以我终于坐下来想出了Windows案例。

具体来说,“Windows案例”是指在Windows中有效的文件名,这意味着它们包含字符\/,{{1 },*?"^<>或换行符。这也意味着|\都被认为是有效的目录分隔符,用于Make。

一个例子将比我能解释的更清楚。基本上,如果您尝试匹配此文件路径:

/

然后你必须写下这些规则:

Child\a$b  {'}(a.o#$@,&+=~`),[].c

长时间盯着它,它会开始有点遥感。

这适用于我的MSYS2环境,因此我认为它是正确的。

答案 2 :(得分:2)

  1. 我不知道makefile是如何工作的。模式规则不能是默认值。
  2. 你错过了`$(通配符......)`中的`$`,所以我觉得你还没有发布你真正测试的内容。
  3. 你也应该逃避换行。