Что не так со следующим расширением переменной оболочки GNU make?

В этой строке:

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.

Что не так с моей дурацкой обходной переменной?

Обновление0

$ 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

person Matt Joiner    schedule 12.08.2011    source источник
comment
Кстати, что не так с $(shell gcc -v 2>&1 | tail -1 | awk '{print $$3}') ?   -  person reinierpost    schedule 12.08.2011
comment
@reinierpost: Ничего, кроме того, что я не знал об этом.   -  person Matt Joiner    schedule 12.08.2011


Ответы (1)


при использовании $ для Bash внутри Makefile вам нужно удвоить их: например, $$a. Я не знаком с обозначением $', но должен предположить, что вы знаете, что с этим делать. если это не конструкция Makefile, вам также нужно удвоить знак доллара на ней.

Кроме того, знак решетки # завершает расширение оболочки в оценке Make, поэтому он никогда не видит правильную скобку. побег от него помогает, но у меня он еще не работает совсем правильно.

Я отлаживаю его, выполнив два шага: сначала устанавливаю 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

Поскольку ваша система работает не так, как моя, я собираюсь отговориться и сказать, что либо используйте предложение рейньерпоста, либо, в качестве альтернативы:

GCCVER := $(shell gcc -dumpversion | cut -d. -f1,2)
person jcomeau_ictx    schedule 12.08.2011
comment
все еще проверяю... это не вся твоя проблема. - person jcomeau_ictx; 12.08.2011
comment
опция -e для эха была необходима для интерполяции \n. - person jcomeau_ictx; 12.08.2011
comment
$'' оценивает содержимое как строку C. - person Matt Joiner; 12.08.2011
comment
Ладно, поверю тебе на слово! Но, как видите, работает и без него. - person jcomeau_ictx; 12.08.2011
comment
Большие усилия, но я получаю <stdin>:1:1: error: stray ‘#’ in program. - person Matt Joiner; 12.08.2011
comment
как выглядит GCCVER, если вы не оборачиваете $(shell) вокруг него? - person jcomeau_ictx; 12.08.2011
comment
Я не могу повторить вашу ошибку. Какую ОС вы используете? У меня стабильный Debian. - person jcomeau_ictx; 13.08.2011
comment
Я добавил соответствующую информацию о версии в вопрос, вот вывод версии $, preshell в соответствии с вашим абзацем ранее о том, как сбрасывать его содержимое: GCCVER='a=`mktemp` && echo $'"'"'#include <stdio.h>\nmain() {printf("%u.%u\\n", __GNUC__, __GNUC_MINOR__);}'"'"' | gcc -o "$a" -xc -; "$a"; rm "$a"' - person Matt Joiner; 13.08.2011
comment
@jcomeau_ictx позвольте нам продолжить это обсуждение в чате - person Matt Joiner; 13.08.2011
comment
Спасибо за комментарий о #. Это сэкономило мне время. - person Matt Messersmith; 27.11.2017