以下GNU make shell变量扩展有什么问题?

时间:2011-08-12 06:24:36

标签: shell gcc makefile gnu-make variable-expansion

在这一行:

GCCVER:=$(shell a=`mktemp` && echo $'#include <stdio.h>\nmain() {printf("%u.%u\\n", __GNUC__, __GNUC_MINOR__);}' | gcc -o "$a" -xc -; "$a"; rm "$a")

我明白了:

*** unterminated call to function `shell': missing `)'.  Stop.

我愚蠢的迂回变量出了什么问题?

Update0

$ make --version
GNU Make 3.81
$ bash --version
GNU bash, version 4.2.8(1)-release (x86_64-pc-linux-gnu)
$ uname -a
Linux 2.6.38-10-generic #46-Ubuntu SMP x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2

1 个答案:

答案 0 :(得分:12)

在Makefile中使用$进行Bash时,需要将它们加倍:例如$$a。我不熟悉符号$',但我必须假设你知道你在做什么。除非它是一个Makefile构造,否则你需要在该构造上加倍美元符号。

此外,哈希符号#正在Make的评估中终止shell扩展,这就是为什么它永远不会看到正确的paren。逃避它有所帮助,但我还没有正常工作。

我正在通过两个步骤来调试它:首先是将GCCVER设置为没有封闭$(shell)的命令列表,然后是第二步设置GCCVER := $(shell $(GCCVER))。您也可以尝试这样做,在$(shell)步骤不成功时使用export注释掉,并制作“设置”食谱:

GCCVER := some commands here
#GCCVER := $(shell $(GCCVER))  # expand the commands, commented out now
export  # all variables available to shell
set:
        set  # make sure this is prefixed by a tab, not spaces

然后:

make set | grep GCCVER

[更新]这有效:

GCCVER := a=`mktemp` && echo -e '\#include <stdio.h>\nmain() {printf("%u.%u\\n", __GNUC__, __GNUC_MINOR__);}' | gcc -o "$$a" -xc -; "$$a"; rm "$$a"
GCCVER := $(shell $(GCCVER))
export
default:
    set

jcomeau@intrepid:/tmp$ make | grep GCCVER
GCCVER=4.6

完整的循环,摆脱了额外的一步:

jcomeau@intrepid:/tmp$ make | grep GCCVER; cat Makefile 
GCCVER=4.6
GCCVER := $(shell a=`mktemp` && echo -e '\#include <stdio.h>\nmain() {printf("%u.%u\\n", __GNUC__, __GNUC_MINOR__);}' | gcc -o "$$a" -xc -; "$$a"; rm "$$a")
export
default:
    set

使用$' Bash构造:

jcomeau@intrepid:/tmp$ make | grep GCCVER; cat Makefile 
GCCVER=4.6
GCCVER := $(shell a=`mktemp` && echo $$'\#include <stdio.h>\nmain() {printf("%u.%u\\n", __GNUC__, __GNUC_MINOR__);}' | gcc -o "$$a" -xc -; "$$a"; rm "$$a")
export
default:
    set

由于你的系统与我的系统不一样,我会发出警告说要么使用reinierpost的建议,要么就是:

GCCVER := $(shell gcc -dumpversion | cut -d. -f1,2)