Makefile shell调用中的哈希导致意外行为

时间:2012-01-29 09:35:12

标签: shell g++ makefile echo

以下命令根据g ++认为的位置打印特定C ++标头的绝对路径。

echo \#include\<ham/hamsterdb.h\> | g++ -M -x c++-header - | grep hamsterdb.hpp | sed -e 's/-:  //' -e 's/ \\//'

在我的系统上,输出:/usr/local/include/ham/hamsterdb.hpp

尝试在Makefile中运行它以设置变量时遇到问题:

FILE=$(shell echo \#include\<ham/hamsterdb.h\> | g++ -M -x c++-header - | grep hamsterdb.hpp | sed -e 's/-:  //' -e 's/ \\//')

.PHONY spec

spec:
    @echo $(FILE)

这会输出一个新行。我认为这是混乱make的哈希('#')字符;如果我像这样重写FILE=...行:

FILE=$(shell echo \#include\<ham/hamsterdb.h\>)

输出仍然没有。

2 个答案:

答案 0 :(得分:11)

你必须两次转义哈希才能在函数中使用它:一次用于Make,一次用于shell。

即,

FILE = $(shell echo \\\#include\ \<ham/hamsterdb.h\>)

注意三个反斜杠,而不是人们所期望的两个反斜杠。第三个反斜杠是必需的,否则第一个反斜杠将逃脱第二个,并且哈希仍然没有转义。

UPD。

另一种可能的解决方案是仅转义Make的哈希并使用Bash单引号来防止将哈希解释为shell注释。这也消除了转义空格<>

的需要
FILE = $(shell echo '\#include <ham/hamsterdb.h>')

答案 1 :(得分:1)

你需要更多引用:

FILE=$(shell echo \\\#include\<ham/hamsterdb.h\> ...
                  ^^^

引用一次make本身,第二次引用shell(shell需要'看'\#)。