4

テキスト ファイルからコンパイルのバージョンを取得しようとしています。私はこのコマンドを使用しています

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

正常に動作しますが、シェルを使用して Makefile から実行しようとしています:

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

が原因で動作させることができません|。たとえば grep というコマンドを 1 つだけ入力すると、正常に実行されます|。式を連結することを示す別の方法はありますか? または、他にどのようにこれを行うことができますか?

編集:

こんにちは、答えてくれてありがとう、

あなたの答えを読んで、コピー/貼り付けが私を裏切ったことに気づきました。これは私が使用している正しい表現です:

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

これは Makefile の出力です。

  • 関数 shell': missing)' への呼び出しが終了していません。止まる。

あなたの推奨事項をテストしましたが、同じエラーで失敗します。

ありがとう。

4

1 に答える 1

6

パイプとは関係ありません。動作しない理由は、動的マクロとして定義したためです。「=」を使用すると、参照ごとにマクロが再評価されます。VERSIONバージョンとファイル名の両方として変数をオーバーロードしようとすることで、本質的に再帰マクロを作成しました。別の変数名を使用してみて、静的にします。

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

$(error VERSION_NUMBER=$(VERSION_NUMBER))

機能したら $(error) を削除します。また、とにかくこの場合、 awk の方が効率的かもしれません:

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

ハッシュの問題もあります(米国の仲間にポンドを)#。式をコメントとして終了しています。これを試して:

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

またはこれ:

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

make の多くの文字でこの問題が発生します。脱出するのに最も問題があるのはドルです。次のような表現を見たことがあります。

V:=$(foreach f,$(list),$(eval $(shell create_rule $$$$(f))))

シェルスクリプトを書いてそれを呼び出す方が良い場合もあります:

script.sh:

#!/bin/sh

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

メイクファイル:

VERSION=$(shell script.sh server.h)
于 2013-08-23T09:35:37.683 に答える