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

发布于 2024-11-28 23:50:36 字数 597 浏览 1 评论 0原文

在这一行上:

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

On this line:

GCCVER:=$(shell a=`mktemp` && echo 

I get:

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

What's wrong with my stupidly circuitous variable?

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
#include <stdio.h>\nmain() {printf("%u.%u\\n", __GNUC__, __GNUC_MINOR__);}' | gcc -o "$a" -xc -; "$a"; rm "$a")

I get:

What's wrong with my stupidly circuitous variable?

Update0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小草泠泠 2024-12-05 23:50:36

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

另外,井号 # 会终止 Make 求值中的 shell 扩展,这就是为什么它永远看不到正确的括号。逃避它有帮助,但我还没有让它正常工作。

我通过两个步骤来调试它:首先将 GCCVER 设置为不包含 $(shell) 的命令列表,然后在第二步中设置 GCCVER := $(shell $(GCCVER))。您可能也想尝试一下,当它不起作用时注释掉 $(shell) 步骤,使用 export 并制作一个“set”配方:

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)

when using $ for Bash inside a Makefile, you need to double them: $$a for example. I'm not familiar with the notation $' but I'll have to assume you know what you're doing with that. unless it's a Makefile construct, you need to double the dollar sign on that one too.

also, the hash sign # is terminating the shell expansion in Make's evaluation, which is why it never sees the right paren. escaping it helps, but I don't have it working quite right yet.

I'm debugging it by having two steps: first is setting GCCVER to be the list of commands without the enclosing $(shell), then in the 2nd step setting GCCVER := $(shell $(GCCVER)). you might want to try that too, commenting out the $(shell) step when it doesn't work, using export, and making a "set" recipe:

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

Then:

make set | grep GCCVER

[update] this works:

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

And full circle, having gotten rid of the extra step:

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

Using the $' Bash construct:

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

Since your system doesn't work the same as mine, I'm going to cop out and say either use reinierpost's suggestion or, alternatively:

GCCVER := $(shell gcc -dumpversion | cut -d. -f1,2)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文