Makefile中的多个Shell命令

use*_*449 3 makefile

我正试图从文本文件中获取我的编译版本.我正在使用这个命令

grep -w -m 1 "V1" server.h | sed $(VERSION) 's/#define V1[\t]//'
Run Code Online (Sandbox Code Playgroud)

它工作正常,但现在我正在尝试使用shell从我的Makefile执行它:

VERSION=$(shell grep -w -m 1 "V1" server.h | sed $(VERSION) 's/#define V1[\t]//')
Run Code Online (Sandbox Code Playgroud)

但由于这个原因,我无法让它发挥作用|.如果我只输入一个命令,例如grep运行正常,还有另一种表示|连接表达式的方法吗?或者我怎么能这样做?

编辑:

嗨,谢谢你的回答,

阅读你的答案我意识到复制/粘贴背叛了我jeje,这是我正在使用的正确表达:

版本:= $(shell grep -w -m 1"V2"server.h | sed's/#define V2 [\ t] //')

这是Makefile的输出:

  • 未终止调用函数shell':missing)'.停止.

我已经测试了你的建议,它也失败了同样的错误.

谢谢.

Cra*_*aig 6

它与管道无关.它无法工作的原因是因为您已将其定义为动态宏.通过使用'=',它将重新评估每个引用上的宏.您实际上通过尝试将VERSION变量作为版本和文件名重载来创建递归宏.尝试使用不同的变量名称并将其设置为静态:

VERSION_NUMBER:=$(shell grep -w -m 1 "V1" server.h | sed $(VERSION) 's/#define V1[\t]//')

$(error VERSION_NUMBER=$(VERSION_NUMBER))
Run Code Online (Sandbox Code Playgroud)

一旦你有工作,删除$(错误).此外,无论如何,awk在这种情况下可能更有效:

VERSION_NUMBER:=$(shell awk '/\<V1\>/ { print gensub(/^\#define V1[[:space:]]+/, "", ""); exit }' $(VERSION))
Run Code Online (Sandbox Code Playgroud)

你也有哈希的问题(对你来说是英镑)#.它将表达式作为注释终止.试试这个:

VERSION:=$(shell grep -w -m 1 "V2" server.h | sed 's/\#define V2[\t]//')
Run Code Online (Sandbox Code Playgroud)

或这个:

VERSION:=$(shell awk '/\<V1\>/ { print gensub(/^\#define V1[[:space:]]+/, "", ""); exit }' server.h)
Run Code Online (Sandbox Code Playgroud)

make中有很多字符会出现此问题.美元是最容易逃脱的问题.我见过这样的表达式:

V:=$(foreach f,$(list),$(eval $(shell create_rule $$$$(f))))
Run Code Online (Sandbox Code Playgroud)

有时最好编写一个shell脚本并调用它:

script.sh:

#!/bin/sh

awk '/\<V1\>/ { print gensub(/^#define V1[[:space:]]+/, "", ""); exit }' "$@"
Run Code Online (Sandbox Code Playgroud)

Makefile文件:

VERSION=$(shell script.sh server.h)
Run Code Online (Sandbox Code Playgroud)